I'm using imagettftext
and imageTTFBbox
to convert strings to images of strings.
For example, this string below
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.
becomes
However, the last line or so is being cut off.
My setup consists of the following: a wrapper function to wrap text (working perfectly fine), and the main img2Text function that's shown below:
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;
}
I believe the problem lies in the imageTTFBox built-in function or my usage of it to calculate the height of the image. It seems to underestimate the height with longer strings of text. The relevant line of code is line 6
, which I have reproduced below for convenience:
$H = ($H==0)?abs($_bx[5]-$_bx[3]):$H;
for reference:
$_bx = imageTTFBbox($fsize,0,$font,$text);
and for the uninitiated imageTTFBbox:
array imagettfbbox ( float $size , float $angle , string $fontfile , string $text )
This function calculates and returns the bounding box in pixels for a TrueType text.
EDIT
timclutton's answer makes sense, and I've tried removing the $__H += 6;
line and it does help. Now only the very last bit gets cut off. (see image below)
The image is created at the start of the function based on the dimensions returned by
imagettfbbox()
, but then at the end of yourforeach
loop you add a 'line-spacing' of +6 via$__H += 6;
. This causes the vertical text size to increase beyond the originally measured dimensions.You can test this by removing that line and seeing that the text now fits into the image.
If you want to include additional line-spacing you should create a variable for it at the start of the function and then create the image based on the dimensions returned by
imagettfbbox()
plus the line-spacing value multiplied by the number of lines.I've rewritten your function as the following:
This gives me the following output, which seems to be what you are aiming for: