Friday, December 21, 2012

Render Text in PNG Format using PHP GD2 in IIS Environment

The following example won't work if you are running GD version 1 in your PHP server. Some modications are required to make it work.

GD's imagettftext by default cannot set the spacing between characters. If you want to force spacing between characters, you can display each character at a time calculating the spacing your self using a loop.

However, there is one problem setting the spacing: each character's width is different. Therefore, the spacing varies depending on the width of each character.

We use imagettfbbox to measure the width of a character with a given font.

imagettfbbox is troublesome as it is using different requirement to specify the font location in IIS. For Linux environment, you also need to add './' in front of the relative font location. As for IIS, absolute font location is needed. dirname(__FILE__) is used to specify the absolute current script location.

If the font's location is not specified correctly, the error of "Warning: imagettfbbox(): Invalid font filename in ..." will be produced.

Even the location is specified correctly, imagettfbbox gives different result according to the GD version. The following example codes are targeted for GD version 2. If you are using GD version 1, you can modify the codes a bit to make it work.

For imagettfbbox in GD 2 environment, an array of 8 elements are returned. Each data in the array represents a x or y coordinate in the bounding box of a character:

For my case, I use x1 to deduct from x2 to get the width of the character.

Finally, enough said, here are the codes:


// Make sure you have the font arialbd.ttf in the ./font directory

$height = 40;
$width = 80;
$text = "test";
$font_space = 9; // You can change the font space here
$font_size = 19;
$angle = 0;
$x = 10;
$y = $height/2 + 7;
$color = 0; // text color black
$bgcolor = '#ffff00';
$font = 'fonts/arialbd.ttf';
$font2 = './fonts/arialbd.ttf';

$img = imagecreatetruecolor($width, $height);
imagefilledrectangle($img, 0, 0, $width - 1, $height - 1, gd_color($bgcolor));

$textlen = strlen($text);
for ($i = 0; $i < $textlen; $i++) {
 $charwidthArr = imagettfbbox(12, 0, dirname(__FILE__).'\\'.$font, $text[$i]);
 $charwidth = $charwidthArr[2] - $charwidthArr[0];
 imagettftext($img, $font_size, $angle, $x, $y, gd_color($color), $font2, $text[$i]);
 $x += $charwidth + $font_space;

header("Content-Type: image/png");

function gd_color($html_color) {
     return preg_match('/^#?([\dA-F]{6})$/i', $html_color, $rgb)
      ? hexdec($rgb[1]) : false;


No comments:

Post a Comment