php imagettftext字母间距

时间:2011-08-03 12:43:32

标签: php gd imagettftext

是否有人使用指定字母间距绘制ttf字符串(imagettftext)的函数?

我找不到任何内置GD功能,所以我认为应该逐字逐句地添加一些恒定的宽度。

也许某人已经有了这样的功能:)

PS。最好的字体是arial.ttf

6 个答案:

答案 0 :(得分:22)

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,则不设置字距调整/字母间距。

答案 1 :(得分:10)

我知道这回答了一段时间,但我需要一个有字母间距并保持角度偏移的解决方案。

我修改了radzi的代码来完成这个:

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]));
        }
    }
}

答案 2 :(得分:6)

只是为了完成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]));
        }
    }
}

答案 3 :(得分: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;
    }
}

答案 4 :(得分:0)

我在这里尝试了所有答案,但似乎没有一个做得不错。如果绘制边界框,则会发生以下情况:

enter image description here

很显然,它们的间距不均匀。由imagettftext()imagettfbbox()返回的边界框似乎只告诉您绘制了什么。这似乎足够了,但由于font kerning,还不够。这意味着即使您说应该在(x,y)处绘制字母,该字母也不是边界框的坐标之一。需要校正字距。 enter image description here

我把这段代码写成了水平文本:

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可以具有任何值。

下面是结果的示例,第一行是普通文本,第二行具有负间距:

enter image description here enter image description here

答案 5 :(得分:-1)

尝试此功能:

$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);