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!

PHP

// 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
117 KB - zip - Version 2


Download the Source - complete with image and font

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

Have Fun! Go Play!

Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


61 subscribers couldn't be wrong*!
Subscribe to the Ninedays Blog feed!
* Not statistically proven, they could be wrong.
Similar Entries
301 Redirects from your Wordpress 404 Error Page
Getting too many 404 requests because you've deleted a post, or moved it/changed it's name. Well there's an easy way to make your Wordpress 404 page redirect to whatever page you need it to!
Direct to Download Images and PDFs
It's really easy to make sure that a file downloads rather than load in a browser, here I walk you through making it happen with a .pdf file as well as a .jpg file.
JavaScript BMI Calculator
Time for some learnin' & JavaScriptin' One thing I had to do for a client a while back was create a JavaScript body mass index calculator. She just wanted 2 fields: Height (inches) Weight (pounds) On that same page she also had a table displaying the translation of BMI calculations from the CDC Website.
MySQL Queries Made Easy With PHP Functions Library
Every web developer has a library of code that they reference frequently, if not constantly. I'm sharing with you one of my most useful snippets my MySQL helper class that helps me organize my queries and easily reference commonly used functions.
Relative Dates in WordPress Templates
One of my favorite trends online is using relative dates like '1 week ago' or '4 days ago' instead of the standard June 11, 2008. I find it helpful in really getting a feel for the freshness of an entry or comment and it's super easy to implement in WordPress.
Next Post
Pre-Overhaul Maintenance
Previous Post
Life on the Blogging D List

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: 6 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!

very useful code for me Thanks.