有没有一个可以绘制指定字母间距的ttf字符串(imagettftext)的函数?
我找不到任何内置的GD函数,所以我认为应该逐个字母地完成,并添加一些常量宽度。
也许有人已经有了这样的功能:)
附注:最好的字体将是arial.ttf
有没有一个可以绘制指定字母间距的ttf字符串(imagettftext)的函数?
我找不到任何内置的GD函数,所以我认为应该逐个字母地完成,并添加一些常量宽度。
也许有人已经有了这样的功能:)
附注:最好的字体将是arial.ttf
function imagettftextSp($image, $size, $angle, $x, $y, $color, $font, $text, $spacing = 0)
{
if ($spacing == 0)
{
imagettftext($image, $size, $angle, $x, $y, $color, $font, $text);
}
else
{
$temp_x = $x;
for ($i = 0; $i < strlen($text); $i++)
{
$bbox = imagettftext($image, $size, $angle, $temp_x, $y, $color, $font, $text[$i]);
$temp_x += $spacing + ($bbox[2] - $bbox[0]);
}
}
}
并且调用:
imagettftextSp($image, 30, 0, 30, 30, $black, 'arial.ttf', $text, 23);
函数参数顺序符合标准的imagettftext参数顺序,并且最后一个参数是可选的$spacing参数。如果未设置或传递的值为0,则不设置字距/字母间距。
function imagettftextSp($image, $size, $angle, $x, $y, $color, $font, $text, $spacing = 0)
{
if ($spacing == 0)
{
imagettftext($image, $size, $angle, $x, $y, $color, $font, $text);
}
else
{
$temp_x = $x;
$temp_y = $y;
for ($i = 0; $i < strlen($text); $i++)
{
imagettftext($image, $size, $angle, $temp_x, $temp_y, $color, $font, $text[$i]);
$bbox = imagettfbbox($size, 0, $font, $text[$i]);
$temp_x += cos(deg2rad($angle)) * ($spacing + ($bbox[2] - $bbox[0]));
$temp_y -= sin(deg2rad($angle)) * ($spacing + ($bbox[2] - $bbox[0]));
}
}
}
补充一下pidalia的回答(最好的答案),以避免在特殊字符(如“é”或“à”)上出现问题。
static function imagettftextSp($image, $size, $angle, $x, $y, $color, $font, $text, $spacing = 0) {
if ($spacing == 0) {
imagettftext($image, $size, $angle, $x, $y, $color, $font, $text);
} else {
$temp_x = $x;
$temp_y = $y;
//to avoid special char problems
$char_array = preg_split('//u',$text, -1, PREG_SPLIT_NO_EMPTY);
foreach($char_array as $char) {
imagettftext($image, $size, $angle, $temp_x, $temp_y, $color, $font, $char);
$bbox = imagettfbbox($size, 0, $font, $char);
$temp_x += cos(deg2rad($angle)) * ($spacing + ($bbox[2] - $bbox[0]));
$temp_y -= sin(deg2rad($angle)) * ($spacing + ($bbox[2] - $bbox[0]));
}
}
}
GD不支持字距调整,所以您需要手动完成。个人建议编写一个函数来单独绘制每个字母。我现在找不到这个函数,但大致的思路是:
function drawText(&$image, $text, $fgColor, $font, $fgColor,
$fontSize = 14, $kerning = 0, $x = 0, $y = 0) {
$letters = explode('', $text);
foreach ($letters as $n => $letter) {
$bbox = imagettftext($image, $fontSize, 0, $x, $y, $fgColor, $font, $letter);
$x += $bbox[2] + $kerning;
}
}
我尝试了所有的答案,但似乎没有一个能够很好地完成工作。如果你绘制边界框,会发生以下情况:
显然它们并不是均匀分布的。似乎由imagettftext()
和imagettfbbox()
返回的边界框只告诉您已绘制的内容。这似乎足够,但实际上并不是这样,因为存在字体字距。这意味着即使您说一个字母应该在(x,y)
处绘制,那也不会是边界框坐标之一。需要对字距进行校正。
我用以下代码拼凑了水平文本:
function getBBoxW($bBox)
{
return $bBox[2] - $bBox[0];
}
function imagettftextSpacing($image, $size, $x, $y, $color, $font, $text, $spacing = 0)
{
$testStr = 'test';
$testW = getBBoxW(imagettfbbox($size, 0, $font, $testStr));
foreach (mb_str_split($text) as $char)
{
$fullBox = imagettfbbox($size, 0, $font, $char . $testStr);
imagettftext($image, $size, 0, $x - $fullBox[0], $y, $color, $font, $char);
$x += $spacing + getBBoxW($fullBox) - $testW;
}
}
$testStr
可以有任何值。尝试使用这个函数:
$image = imagecreatetruecolor(500,200);
$text = "Text to print";
$text_color=imagecolorallocate($image,255,255,255);
$font_size = 18;
$space = 8;
$font = "path_to_font/arial.ttf";
$x=20;
$y=20;
for ($i = 0; $i <strlen($text); $i++){
$arr = imagettftext ($image, $font_size,0, $x, $y, $text_color, $font, $text{$i});
$x = $arr[4]+$space;
}
imagejpeg($image);
destroyimage($image);