Is there a word wrap function for GD2 in php?

2019-04-13 05:56发布

people.

I have slight problem with GD2 text on image. I have everything working and now i try to add text on image that can wrap within image.

For example i have image with width 200px and large block of text. If you use imagettftext() text goes beyond borders of image and only partial text actually is visible. I have tried to use Zend's text wrap function, but it's not always producing accurate results here(not saying it don't work, only not in this case).

Is there some dedicated GD2 method to set some width box where text should fit and if it hits border of that box it should continue in new line?

3条回答
We Are One
2楼-- · 2019-04-13 06:04

The function from safarov contains a small bug which demonstrated for my user case. If I sent a word larger than $width, it would newline every word afterwards, so for example:

veryloooooooooooooongtextblablaOVERFLOWING
this 
should 
be 
one 
line

The reason is, imagettfbox will always be > $width with that "malicious" word inside text. My solution was to simply check each word width separately and optionally cut the word until it fits $width (or cancel the cutting if we get to length 0). Then I proceed with normal wordwrapping. The result is something like:

veryloooooooooooooongtextblabla
this should be one line

Here's the modified function:

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;
}
查看更多
趁早两清
3楼-- · 2019-04-13 06:06

Not sure its what you looking for but, you can try this:

 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;
}
查看更多
聊天终结者
4楼-- · 2019-04-13 06:11

Unfortunately I don't think there's an easy way of doing this. The best you can do is to approximately calculate your image width and how many characters your text in its current font can fit and break it manually on that n'th character.

If you are using a monospace fonts (unlikely, I know), you can get an accurate result as they are evenly spaced.

查看更多
登录 后发表回答