Writing Text to Images with PHP


Wanna make a pretty picture? Well we won't be doing that today, but we will be writing text into an image using PHP.

Every now and then the feds change the interest rates...blah blah stimulate the economy...blah blah.
Well at work we have a financial institution as a client at work who has about half a dozen image on their website displaying the current rates. When the feds make the change we have to drop everything we are doing to make the update.

Not really a big deal since our PSD's are pretty readily accessible but it's sucks up probably 45 minutes of company time.

  • 5 minutes PM getting the request from the client and any clarification then passing on to the designer.
  • 25 minutes designer locates files, makes changes, exports the new versions.
  • 10 minutes developer uploads the new files to the correct location and the developer and PM QC the changes
  • 5 minutes PM crafts and email to the client updating them that the images have been changed

Not a very long process but if there is a way to alleviate some of that time then why not do it?

I spent, probably 3hrs over the weekend preparing this script. Assuming it would take me 2 more hours to prepare an interface where my PM could make the updates automatically in 15 minutes through the CMS and assuming the feds might change this rate on average a dozen times a year.

  • Old solution: 12 * 45min = 9 hours (540min)
  • New solution: (12 * 15min) + 5hrs = 8 hours (5hrs + 180min)

Only saving one hour? Yea, not a huge deal, but the next time it might take only 1 hour to implement a similar solution into another site. Or if the feds change the rate 18 times one year, then there's a boat load more savings.

So let's do it to it!

Start with your base Image

We'll start with a plain square image that I got for free from Dreamstime.

Original image: BEAUTY GIRL JUMPING IN FIELD © Anatoly Tiplyashin | Dreamstime.com

I made a sample in PhotoShop of how the final product should look so I could get my positioning, font size, and color right.

Demo Full Image

Then I removed the rate and had my "blank canvas" to work with.

Demo Usable Image

I choose to save out the blank canvas as a PNG because JPEG's compression would cause distortion in the image when I go to save it back out from the script.

PHP Image Writing Time

I've created a very efficient and simplified image wirting script built inspired by the post PHP + CSS Dynamic Text Replacement (P+C DTR).
Note: This page no longer has the zip file posted but you can find it via the web archive.
Also Note: The P+C DTR script is a build off of an A List Apart article Dynamic Text Replacement.

I'm going to break this down and leave the source available at the end so bear with me while I explain

Start by Formatting Input

This PHP file will not just create and image it will become an image. So we'll be displaying the image on another page like this:

<img src="write-to-image.php" alt="Writing to an Image With PHP" />

And since the text is dynamic we'll force get the variable text like this:

<img src="write-to-image.php?text=4.3%" alt="Writing 4.3% to an Image With PHP" />

So since there's dynamic content being passed let's clean that up:

// clean up the input
if(empty($_GET['text']))    fatal_error('Error: No text specified.') ;

$text = html_entity_decode($_GET['text']).' ' ;
$text = floatval($text);
$text = number_format($text, 1, '.', '') . '%';

if(empty($text))
    fatal_error('Error: Text not properly formatted.') ;

Customizable Variables

After I've uploaded the ttf font file and the image I am going to write on in the same directory as this script I have to change those variables in the script.

// customizable variables
$font_file      = 'font-file.ttf';
$font_size      = 23 ; // font size in pts
$font_color     = '#ffffff' ;
$image_file     = 'image-to-write-on.png';

// x and y for the bottom right of the text
// so it expands like right aligned text
$x_finalpos     = 227;
$y_finalpos     = 103;

This is also the place to set text positioning, font size as well as font color.

More Script You Need Not Edit

The rest of the script is stuff you really don't need/want to edit. I'd hold you hand through all of it but I think you'd leave if I did. Wanna know more, walk through it, add your own comments and PHP.net it!

// trust me for now...in PNG out PNG
$mime_type          = 'image/png' ;
$extension          = '.png' ;
$s_end_buffer_size  = 4096 ;

// check for GD support
if(!function_exists('ImageCreate'))
    fatal_error('Error: Server does not support PHP image generation') ;

// check font availability;
if(!is_readable($font_file)) {
    fatal_error('Error: The server is missing the specified font.') ;
}

// create and measure the text
$font_rgb = hex_to_rgb($font_color) ;
$box = @ImageTTFBBox($font_size,0,$font_file,$text) ;

$text_width = abs($box[2]-$box[0]);
$text_height = abs($box[5]-$box[3]);

$image =  imagecreatefrompng($image_file);

if(!$image || !$box)
{
    fatal_error('Error: The server could not create this image.') ;
}

// allocate colors and measure final text position
$font_color = ImageColorAllocate($image,$font_rgb['red'],$font_rgb['green'],$font_rgb['blue']) ;

$image_width = imagesx($image);

$put_text_x = $image_width - $text_width - ($image_width - $x_finalpos);
$put_text_y = $y_finalpos;

// Write the text
imagettftext($image, $font_size, 0, $put_text_x,  $put_text_y, $font_color, $font_file, $text);


header('Content-type: ' . $mime_type) ;
ImagePNG($image) ;

ImageDestroy($image) ;
exit ;

Functions from the P + C DTR

And these custom functions are used and necessary too:

/*
    attempt to create an image containing the error message given. 
    if this works, the image is sent to the browser. if not, an error
    is logged, and passed back to the browser as a 500 code instead.
*/
function fatal_error($message)
{
    // send an image
    if(function_exists('ImageCreate'))
    {
        $width = ImageFontWidth(5) * strlen($message) + 10 ;
        $height = ImageFontHeight(5) + 10 ;
        if($image = ImageCreate($width,$height))
        {
            $background = ImageColorAllocate($image,255,255,255) ;
            $text_color = ImageColorAllocate($image,0,0,0) ;
            ImageString($image,5,5,5,$message,$text_color) ;    
            header('Content-type: image/png') ;
            ImagePNG($image) ;
            ImageDestroy($image) ;
            exit ;
        }
    }

    // send 500 code
    header("HTTP/1.0 500 Internal Server Error") ;
    print($message) ;
    exit ;
}


/* 
    decode an HTML hex-code into an array of R,G, and B values.
    accepts these formats: (case insensitive) #ffffff, ffffff, #fff, fff 
*/    
function hex_to_rgb($hex) {
    // remove '#'
    if(substr($hex,0,1) == '#')
        $hex = substr($hex,1) ;

    // expand short form ('fff') color to long form ('ffffff')
    if(strlen($hex) == 3) {
        $hex = substr($hex,0,1) . substr($hex,0,1) .
               substr($hex,1,1) . substr($hex,1,1) .
               substr($hex,2,1) . substr($hex,2,1) ;
    }

    if(strlen($hex) != 6)
        fatal_error('Error: Invalid color "'.$hex.'"') ;

    // convert from hexidecimal number systems
    $rgb['red'] = hexdec(substr($hex,0,2)) ;
    $rgb['green'] = hexdec(substr($hex,2,2)) ;
    $rgb['blue'] = hexdec(substr($hex,4,2)) ;

    return $rgb ;
}

End Product

This one really is dynamic:

Dynamic Writing 4.5%

Download

Download the zip file and play! I've changed the font because even though I used Arial Black I don't have the right to distribute it. So your file will probably look like this:

Dynamic Writing 9.2%
Download the Source - complete with image and font

Using and contains the font file Ambient from The Font Garden.

Have Fun! Go Play!

Popularity: 81% [?]


Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Trackbacks & Pingbacks

Pete White - ImAFish 10.2 Seabass - Blog, Articles, Media, Forum Extra!

Gordon Ramsay DONE Image Generator...

After one of my recent rants I used an image of Gordon Ramsay saying 'Done'. I received a number of comments saying how funny it was and how it would make a great Internet meme so I've put together an image generator that lets you create your own Go...

Trackedback: 2 months ago

Reader Comments

Hey great tutorial - I've been able to add text to an image thanks to this. I used the wordwrap function in order to move the text over multiple lines.

Regarding: "write-to-image.php?text=4.3%" alt="Writing 4.3% to an Image With PHP" />

Instead of the above which requires changing a file on the server, how can you change the rate using an using an online form? Seems simple, but I'm not a coder/programmer : )

Terri Ann, you Writing Text to Images with PHP script is really neat.

Is there any way you could post a version of that script with eight input forms that allow numbers or text to be input, with each input form also having variables for text size, font, color and XY coordinates?

Thanks, and again, great script!

This code helps me, Thanks!