Есть ли в php функция переноса слов для GD2? - PullRequest
2 голосов
/ 26 марта 2012

человек.

У меня небольшая проблема с текстом GD2 на изображении. У меня все работает, и теперь я пытаюсь добавить на изображение текст, который можно обернуть в изображение.

Например, у меня есть изображение шириной 200 пикселей и большой блок текста. Если вы используете imagettftext() текст выходит за границы изображения, и на самом деле виден только частичный текст. Я попытался использовать функцию Zend для переноса текста, но она не всегда дает точные результаты (не говоря о том, что она не работает, но только не в этом случае).

Есть ли какой-то специальный метод GD2 для установки некоторого поля ширины, в которое должен помещаться текст, и, если оно достигает границы этого поля, оно должно продолжаться в новой строке?

Ответы [ 3 ]

5 голосов
/ 26 марта 2012

Не уверен, что это то, что вы ищете, но вы можете попробовать это:

 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;
}
3 голосов
/ 22 апреля 2013

Функция от 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;
}
1 голос
/ 26 марта 2012

К сожалению, я не думаю, что есть простой способ сделать это.Лучшее, что вы можете сделать, - это приблизительно рассчитать ширину вашего изображения и количество символов, в которое может поместиться ваш текст в текущем шрифте, и разбить его вручную на этом n-м символе.

Если вы используете моноширинные шрифты (маловероятноЯ знаю), вы можете получить точный результат, так как они равномерно распределены.

...