【问题标题】:php imagettftext letter spacingphp imagettftext 字母间距
【发布时间】:2011-10-19 02:08:54
【问题描述】:

有没有人有绘制具有指定字母间距的 ttf 字符串(imagettftext)的函数?

我找不到任何内置的 GD 函数,所以我认为应该逐个字母添加一些恒定宽度。

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

ps。最好的字体是 arial.ttf

【问题讨论】:

    标签: php gd imagettftext


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      试试这个功能:

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

      【讨论】:

        【解决方案3】:
        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,则不设置字距/字母间距。

        【讨论】:

        • 将 $text[$i] 替换为 mb_substr($text, $i, 1) 以克服多字节字符的问题
        • 虽然我很欣赏这些努力,但我认为这个功能还不够强大。当它像这样迭代时,它会破坏字母间距。你自己看。将间距 0 与间距 0.1 进行比较,您会注意到 0.1 的字距调整最终无处不在。
        【解决方案4】:

        我知道这在不久前就得到了回答,但我需要一个具有字母间距并保持角度偏移的解决方案。

        我修改了 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]));
                }
            }
        }
        

        【讨论】:

        • 很高兴看到您用这个答案回馈了 Stack Overflow 社区。好节目+1
        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          显然它们的间距不均匀。由imagettftext()imagettfbbox() 返回的边界框似乎只告诉您绘制的内容。这似乎足够了,但事实并非如此,因为font kerning。这意味着即使您说应该在(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 可以有任何值。

          这是一个结果示例,第一行是普通文本,第二行是负间距:

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-02-01
            • 2012-10-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多