Log in

View Full Version : Resolved need help calculating font with image width and height



james438
11-01-2019, 12:48 AM
I'm working on a project for a friend that will generate an image of text where the two variables are font and size using php's Graphics Draw (https://www.php.net/manual/en/book.image.php) library.

For this example, I am using the free font After Shok (https://www.wfonts.com/font/after-shok).
The main functions I am trying to wrap my mind around are imagettfbbox (https://www.php.net/manual/en/function.imagettfbbox.php), imagecreatetruecolor (https://www.php.net/manual/en/function.imagecreatetruecolor.php), and imagettftext (https://www.php.net/manual/en/function.imagettftext.php)

The script seems to work great with getting the horizontal, but the vertical height/positioning is off.

The first script displays the position of the image using the imagettfbbox function.


<?php
$text='Imperium';
$font = 'storage/fonts/After_Shok.ttf';
$size=180;
$bbox = imagettfbbox($size, 0, $font, $text);
$width = '0';
$angle = 0;
$a=abs($bbox[3]);
$b=abs($bbox[5]);
$height=$a+$b;
$im = imagecreatetruecolor($bbox[2]-$bbox[0], $height);
$bg = imagecolorallocate($im, 5, 0, 5);
$color = imagecolorallocate($im, 255, 0, 0);
$width = '0';
$angle = 0;
##$height=abs($bbox[3])+abs($bbox[5]);
imagefill($im, 0, 0, 5);
imagettftext($im, $size, $angle, $width-$bbox[0], $size+10, $color, $font, $text);
echo "width=$width-$bbox[0]<br>height=$size+10<br>
lower left corner = $bbox[0],$bbox[1]<br>
lower right corner = $bbox[2], $bbox[3]<br>
upper right corner = $bbox[4], $bbox[5]<br>
upper left corner = $bbox[6], $bbox[7]<br>";
##header('Content-type: image/png');
##imagepng($im);
imagedestroy($im);
?>

The second script, which is nearly identical to the first, will display the image.


<?php
$text='Imperium';
$font = 'storage/fonts/After_Shok.ttf';
$size=18;
$bbox = imagettfbbox($size, 0, $font, $text);
$width = '0';
$angle = 0;
$a=abs($bbox[3]);
$b=abs($bbox[5]);
$height=$a+$b;
$im = imagecreatetruecolor($bbox[2]-$bbox[0], $height);
$bg = imagecolorallocate($im, 5, 0, 5);
$color = imagecolorallocate($im, 255, 0, 0);
$width = '0';
$angle = 0;
##$height=abs($bbox[3])+abs($bbox[5]);
imagefill($im, 0, 0, 5);
imagettftext($im, $size, $angle, $width-$bbox[0], $size+10, $color, $font, $text);
##echo "width=$width-$bbox[0]<br>height=$size+10<br>
##lower left corner = $bbox[0],$bbox[1]<br>
##lower right corner = $bbox[2], $bbox[3]<br>
##upper right corner = $bbox[4], $bbox[5]<br>
##upper left corner = $bbox[6], $bbox[7]<br>";
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

Feel free to play around with it. I'm open to any criticism and ideas.

james438
11-02-2019, 02:29 AM
I now have a script that works. I want to refine the code before I post it. I also need to look it over for possible bugs.

The big clue to solving this was when I figured out that the width between -1 and 1 is not 2, but 3. After that, understanding the width and height of the box and the positioning of the text inside the box began to fall into place.

james438
11-02-2019, 03:34 AM
There may still be bugs that I have missed, but here it is:


<?php
$text = 'uu';
$font = 'ImperatorSmallCapsBold.ttf';
$size = 300;
$bbox = imagettfbbox($size, 0, $font, $text);
$width = 0;
$box_width=abs($bbox[0]-$bbox[2]);
$angle = 0;
$a = 0;
$height=abs($bbox[3])+abs($bbox[5]);
if ($bbox[3]<1 or $bbox[5]<1) $a=1;
$img = imagecreatetruecolor($box_width, $height+$a);
$bg = imagecolorallocate($img, 5, 0, 5);
$color = imagecolorallocate($img, 255, 0, 0);
imagefill($img, 0, 0, $bg);
$h_position=$width-$bbox[0];
$v_position=$height-$a;
imagettftext($img, $size, $angle, $h_position, $v_position, $color, $font, $text);
header('Content-type: image/png');
imagepng($img);
imagedestroy($img);
?>

This script will create a box and write text to that box. The boundaries of the box are a pixel perfect match for the boundaries of the text, so that no text is cut off and there is no excess space wasted horizontally or vertically.

Some possible uses include writing custom text onto an image, creating a logo with a transparent background, creating a watermark onto an image.

I tried this with four different fonts. Not a lot, so if anyone tries a font that does not work, please let me know.

Variables in the script to change include the following:


$text = 'uu';
$font = 'ImperatorSmallCapsBold.ttf';
$size = 300;

color can be in the following format:


$color = imagecolorallocate($img, 255, 0, 0);
$color='009900';

to make the background transparent add the following before the header:


imagecolortransparent($img, $bg);

Limitations:


Only works with .ttf fonts.
Changing the angle of the script causes the text to not fit the box.