Почему мои последние слова обрезаются?

я использую imagettftext а также imageTTFBbox конвертировать строки в изображения строк.

Например, эта строка ниже

Эта планета имеет — или, скорее, имела — проблему, которая заключалась в следующем: большинство людей, живущих на ней, были несчастливы почти все время. Для этой проблемы было предложено много решений, но большинство из них были в основном связаны с движением маленьких зеленых кусочков бумаги, что было странно, потому что в целом не маленькие несчастные листочки бумаги были несчастны.

становится

IMG

Тем не менее, последняя строка или около того обрезается.

Моя установка состоит из следующего: функция-обертка для переноса текста (работает отлично) и основная функция img2Text, показанная ниже:

function imagettfJustifytext($text, $font="../../fonts/Roboto-Light.ttf", $Justify=2, $W=0, $H=0, $X=0, $Y=0, $fsize=12, $color=array(0x0,0x0,0x0), $bgcolor=array(0xFF,0xFF,0xFF)){
$angle = 0;
$L_R_C = $Justify;
$_bx = imageTTFBbox($fsize,0,$font,$text);

$W = ($W==0)?abs($_bx[2]-$_bx[0]):$W;
$H = ($H==0)?abs($_bx[5]-$_bx[3]):$H;

$im = @imagecreate($W, $H)
or die("Cannot Initialize new GD image stream");

$background_color = imagecolorallocate($im, $bgcolor[0], $bgcolor[1], $bgcolor[2]);
$text_color = imagecolorallocate($im, $color[0], $color[1], $color[2]);

if($L_R_C == 0){ //Justify Left
imagettftext($im, $fsize, $angle, $X, $fsize, $text_color, $font, $text);
} elseif ($L_R_C == 1) { //Justify Right
$s = split("[\n]+", $text);
$__H=0;
foreach($s as $key=>$val){
$_b = imageTTFBbox($fsize,0,$font,$val);
$_W = abs($_b[2]-$_b[0]);
$_X = $W-$_W;
$_H = abs($_b[5]-$_b[3]);
$__H += $_H;
imagettftext($im, $fsize, $angle, $_X, $__H, $text_color, $font, $val);
$__H += 6;
}
} elseif ($L_R_C == 2) { //Justify Center
$s = split("[\n]+", $text);
$__H=0;
foreach($s as $key=>$val){
$_b = imageTTFBbox($fsize,0,$font,$val);
$_W = abs($_b[2]-$_b[0]);
$_X = abs($W/2)-abs($_W/2);
$_H = abs($_b[5]-$_b[3]);
$__H += $_H;
imagettftext($im, $fsize, $angle, $_X, $__H, $text_color, $font, $val);
$__H += 6;
}
}
return $im;
}

Я полагаю, что проблема заключается во встроенной функции imageTTFBox или в ее использовании для вычисления высоты изображения. Кажется, недооценивать высоту с более длинными строками текста. Соответствующая строка кода line 6, который я воспроизвел ниже для удобства:

$H = ($H==0)?abs($_bx[5]-$_bx[3]):$H;

для справки:

$_bx = imageTTFBbox($fsize,0,$font,$text);

и для непосвященных imageTTFBbox:

array imagettfbbox ( float $size , float $angle , string $fontfile , string $text )

Эта функция вычисляет и возвращает ограничивающую рамку в пикселях для текста TrueType.

timcluttonответ имеет смысл, и я попытался удалить $__H += 6; линия, и это помогает. Теперь только самый последний бит обрезается. (см. изображение ниже)

img2

1

Решение

Изображение создается в начале функции на основе размеров, возвращаемых imagettfbbox(), но потом в конце твоего foreach цикл вы добавляете «межстрочный интервал» +6 через $__H += 6;, Это приводит к увеличению размера текста по вертикали по сравнению с первоначально измеренными размерами.

Вы можете проверить это, удалив эту строку и увидев, что текст теперь вписывается в изображение.

Если вы хотите включить дополнительный межстрочный интервал, вы должны создать для него переменную в начале функции, а затем создать изображение на основе измерений, возвращаемых imagettfbbox() плюс значение межстрочного интервала, умноженное на количество строк.


Я переписал вашу функцию следующим образом:

function imagettftextalign($text, $align = 0, $fsize = 12, $color = array(0x0, 0x0, 0x0), $bgcolor = array(0xFF, 0xFF, 0xFF), $font = './font/Roboto-Light.ttf', $angle = 0)
{
// measure input text.
$box = imagettfbbox($fsize, $angle, $font, $text);
$w = abs($box[2] - $box[0]);
$h = abs($box[5] - $box[3]);

// create resources.
$im = imagecreatetruecolor($w, $h);
$background_color = imagecolorallocate($im, $bgcolor[0], $bgcolor[1], $bgcolor[2]);
$text_color = imagecolorallocate($im, $color[0], $color[1], $color[2]);

// set background.
imagefilledrectangle($im, 0, 0, $w, $h, $background_color);

// split text by line and get line height.
$lines = explode("\n", $text);
$lh = floor($h / count($lines));

// output lines.
$y = ($lh * .8); // note: this is a guesstimate at the font baseline!
foreach ($lines as $line) {
if ($align > 0) {
$box = imagettfbbox($fsize, $angle, $font, $line);
$lw = abs($box[2] - $box[0]); // line width.
switch ($align) {
case 1: // centre.
$x = ($w / 2) - ($lw / 2);
break;
case 2: // right.
$x = $w - $lw;
break;
}
} else {
$x = 0;
}

imagettftext($im, $fsize, $angle, $x, $y, $text_color, $font, $line);
$y += $lh; // increment line y position.
}

return $im;
}

$txt = "This planet has — or rather had — a problem, which
was this: most of the people living on it were unhappy
for pretty much all of the time. Many solutions were
suggested for this problem, but most of these were
largely concerned with the movement of small green
pieces of paper, which was odd because on the whole
it wasn't the small green pieces of paper that were
unhappy.";

$im = imagettftextalign($txt, 1);

header('Content-type: image/png');
imagepng($im);

Это дает мне следующий результат, который, кажется, является тем, к чему вы стремитесь:

пример вывода функции

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]