Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to determine text coordinates a from bounding box?

Given the result of a call to imagettfbbox(), what is the correct, pixel-perfect point to provide to imagettftext() such that the text will not extend beyond its bounding box?

I am determining the width/height and x/y of the baseline from the bounding box like this:

$box = imagettfbbox($size, $angle, $font, $text);
$boxXCoords = array($box[0], $box[2], $box[4], $box[6]);
$boxYCoords = array($box[1], $box[3], $box[5], $box[7]);
$boxWidth = max($boxXCoords) - min($boxXCoords);
$boxHeight = max($boxYCoords) - min($boxYCoords);
$boxBaseX = abs(min($boxXCoords));
$boxBaseY = abs(min($boxYCoords));

I then draw a filled rectangle on my image of the dimensions of the bounding box:

imagefilledrectangle($image, 0, 0, $boxWidth - 1, $boxHeight - 1, $color);

After that, I draw the text:

imagettftext($image, $size, $angle, $boxBaseX, $boxBaseY, $color, $font, $text);

However, this causes the text to extend beyond the rectangle by a pixel or two. I have seen several attempts to fix this issue on PHP's imagettfbbox() documentation, but they all just suggest substracting a pixel or two here and there, which seems like a hack to me. What's happening here, and why should we need to fudge the numbers to get things right?

like image 400
FtDRbwLXw6 Avatar asked Jul 26 '12 14:07

FtDRbwLXw6


1 Answers

I believe there is no perfect way to place text with single-pixel precision on an image based on what imagettfbbox() returns and also using .ttf non-monospaced fonts. Over at the PHP manual many users have posted ways to accomplish this (with and without fudging the numbers); I recommend using jodybrabec's simple function over at the PHP manual, which calculates the exact bounding box. I have tested this one and only in extreme cases is the text positioned at most 1 pixel off in one direction. Nonetheless, if you add some padding (even if it is just 2 or 3 pixels) to your image your text will be within the dimensions of the image 100% of the time.

like image 74
dazedviper Avatar answered Oct 20 '22 21:10

dazedviper