Using PHP GD to create image form text with different fonts

Meredith picture Meredith · Jan 9, 2011 · Viewed 10.5k times · Source

I have been using this simple script to generate images from text:

<?php
header('Content-type: image/png');

$color = RgbfromHex($_GET['color']);

$text = urldecode($_GET['text']);

$font = 'arial.ttf';

$im = imagecreatetruecolor(400, 30);

$bg_color = imagecolorallocate($im, 255, 255, 255);

$font_color = imagecolorallocate($im, $color[0], $color[1], $color[2]);

imagefilledrectangle($im, 0, 0, 399, 29, $bg_color);

imagettftext($im, 20, 0, 10, 20, $font_color, $font, $text);

imagepng($im);

imagedestroy($im);

function RgbfromHex($hexValue) {
    if(strlen(trim($hexValue))==6) {
        return array(
                     hexdec(substr($hexValue,0,2)), // R
                     hexdec(substr($hexValue,2,2)), // G
                     hexdec(substr($hexValue,4,2))  // B
                    );
    }
    else return array(0, 0, 0);
}

?>

I call the script with file.php?text=testing script&color=000000

Now I'd like to know how could I generate text with normal and bold fonts mixed in the same image, something like file.php?text=testing <b>script</b>&color=000000


Thanks to dqhendricks for helping me figure this out.

Here's a quick script I wrote, still needs lot of improvements but for the basic functionality it seems to be working fine:

<?php
header('Content-type: image/png');

$color = RgbfromHex($_GET['color']);

$im = imagecreatetruecolor(400, 30);

$white = imagecolorallocate($im, 255, 255, 255);

imagefilledrectangle($im, 0, 0, 399, 29, $white);

$tmp = $_GET['text'];

$words = explode(" ", $tmp);

$x = array(0,0,10); // DUMMY ARRAY WITH X POSITION FOR FIRST WORD

$addSpace = 0;

foreach($words as $word)
{
    if($addSpace) $word = " ".$word; // IF WORD IS NOT THE FIRST ONE, THEN ADD SPACE

    if(stristr($word, "<b>"))
    {
        $font = 'arialbd.ttf'; // BOLD FONT
        $x = imagettftext($im, 20, 0, $x[2], 20, imagecolorallocate($im, $color[0], $color[1], $color[2]), $font, str_replace(array("<b>","</b>"), "", $word));
    }
    else
    {
        $font = 'arial.ttf'; // NORMAL FONT
        $x = imagettftext($im, 20, 0, $x[2], 20, imagecolorallocate($im, $color[0], $color[1], $color[2]), $font, $word);
    }

    $addSpace = 1;
}

imagepng($im);

imagedestroy($im);

function RgbfromHex($hexValue) {
    if(strlen(trim($hexValue))==6) {
        return array(
                     hexdec(substr($hexValue,0,2)), // R
                     hexdec(substr($hexValue,2,2)), // G
                     hexdec(substr($hexValue,4,2))  // B
                    );
    }
    else return array(0, 0, 0);
}

?>

Note: This will only work for "bolding" single words separated by spaces and not for bolding part of a word.

Call the script with file.php?text=testing+<b>script</b>&color=000000

Answer

dqhendricks picture dqhendricks · Jan 9, 2011

you will need to load an arial-bold font file, and do two separate imagettftext() calls, one with each font you want to use. as for parsing the string to find out which parts you would like to be bold, and where you should print each section of text, this sounds like it will become very complicated code. what are you even using this for? there may be better solutions for accomplishing the same thing.

Addition

Use the return value from the imagettftext() function to determine where the next text print should start.

From documentation:

Returns an array with 8 elements representing four points making the bounding box of the text. The order of the points is lower left, lower right, upper right, upper left. The points are relative to the text regardless of the angle, so "upper left" means in the top left-hand corner when you see the text horizontally. Returns FALSE on error.