2

人们。

我对图像上的 GD2 文字有一点问题。我一切正常,现在我尝试在图像上添加可以包裹在图像中的文本。

例如,我有宽度为 200 像素的图像和大块文本。如果您使用imagettftext()文本超出图像边界,则实际上只有部分文本可见。我曾尝试使用 Zend 的文本换行功能,但它并不总是在这里产生准确的结果(不是说它不起作用,只是在这种情况下不是)。

是否有一些专用的 GD2 方法来设置一些文本应该适合的宽度框,如果它碰到该框的边框,它应该在新行中继续?

4

3 回答 3

5

不确定它是你在找什么,但你可以试试这个:

 function wrap($fontSize, $fontFace, $string, $width){

    $ret = "";
    $arr = explode(' ', $string);

    foreach ( $arr as $word ){
      $teststring = $ret.' '.$word;
      $testbox = imagettfbbox($fontSize, 0, $fontFace, $teststring);
     if ( $testbox[2] > $width ){
       $ret.=($ret==""?"":"\n").$word;
      } else {
        $ret.=($ret==""?"":' ').$word;
      }
    }

  return $ret;
}
于 2012-03-26T10:19:47.987 回答
3

来自 safarov 的函数包含一个小错误,该错误已针对我的用户案例进行了演示。如果我发送一个大于 $width 的单词,它会在之后换行每个单词,例如:

veryloooooooooooooongtextblablaOVERFLOWING
this 
should 
be 
one 
line

原因是,在文本中带有“恶意”字词的 imagettfbox 将始终 > $width。我的解决方案是简单地分别检查每个单词的宽度,并选择性地剪切单词,直到它适合 $width(或者如果我们达到长度 0,则取消剪切)。然后我继续进行正常的自动换行。结果是这样的:

veryloooooooooooooongtextblabla
this should be one line

这是修改后的功能:

function wrap($fontSize, $fontFace, $string, $width) {

    $ret = "";
    $arr = explode(" ", $string);

    foreach ( $arr as $word ){
      $testboxWord = imagettfbbox($fontSize, 0, $fontFace, $word);

      // huge word larger than $width, we need to cut it internally until it fits the width
      $len = strlen($word);
      while ( $testboxWord[2] > $width && $len > 0) {
        $word = substr($word, 0, $len);
        $len--;
        $testboxWord = imagettfbbox($fontSize, 0, $fontFace, $word);
      }

      $teststring = $ret.' '.$word;
      $testboxString = imagettfbbox($fontSize, 0, $fontFace, $teststring);
      if ( $testboxString[2] > $width ){
        $ret.=($ret==""?"":"\n").$word;
       } else {
         $ret.=($ret==""?"":' ').$word;
      }
    }

  return $ret;
}
于 2013-04-22T14:43:35.670 回答
1

不幸的是,我认为没有一种简单的方法可以做到这一点。您可以做的最好的事情是近似计算您的图像宽度以及当前字体中的文本可以容纳多少个字符,并在第 n 个字符上手动打破它。

如果您使用的是等宽字体(我知道这不太可能),您可以获得准确的结果,因为它们是均匀分布的。

于 2012-03-26T10:16:28.913 回答