Creating images on-the-fly can be a very useful skill. Using PHP’s built-in image generation functions, it’s pretty easy, too. This tutorial will detail how to have the titles of blog entries show up as automatically generated images.

What we’ll be doing is passing arguments via the URL to a separate file that will be our image. Why use a separate file? Because of headers. If you try to generate an image in the middle of a regular PHP or HTML page, you’re going to get an error about the headers having already been sent. That’s because with the first bit of text or HTML that got passed, the page was determined to be an HTML page. By attempting to generate an image in the middle of it, you’re essentially trying to say, “Oh wait, this HTML is suddenly going to become a GIF,” which isn’t possible. Therefore, we’ll use a separate file where no text data is echoed, and pass the headers manually, via the header() function, declaring the file to be an image.

So create a file called image.php. In that file, we’ll put all our image-generating code. Since we’re going to want the image to be dynamic (i.e. its content changes based on what the title of our blog entry is), we’re going to need to pass arguments to it. The simplest way to do that is via the $_GET superglobal. $_GET is just an associative array consisting of all the key/value pairs passed in the URL. You may have seen URL’s such as index.php?page=about_me before. In $_GET, there would be an index ‘page’ and its value would be about_me.

image.php

1
2
3
4
if ( array_key_exists('text', $_GET) )
     $text = $_GET['text'];
else
     $text = 'No title supplied';

What this is doing is testing to see if the index ‘text’ exists in $_GET. If it does, store that value in $text; if it doesn’t exist, then that means no value for ‘text’ was passed in the URL, and therefore we want to supply some default value (i.e. ‘No title supplied’).

Your entry titles may well have funny characters, such as spaces, slashes, and quotes, in them that won’t work well if you just pass them as-is in a URL. Therefore, you’ll need to use urlencode() on any text that you send to image.php. After receiving it, though, you don’t want your image to have the encoded version of the entry title, so you’ll need to decode it like so:

1
$text = urldecode( $text );

Now that we have a way of getting our entry title, we can move on to doing something useful with it. To create an image in PHP, you’ll use the imagecreate() function. You’ll then want to define some colors with imagecolorallocate() to use throughout the image, the first of which will be set as the background color:

1
2
3
$image = imagecreate( 200, 40 );
$white = imagecolorallocate( $image, 255, 255, 255 );
$black = imagecolorallocate( $image, 0, 0, 0 );

This is creating an image that’s 200 pixels wide by 40 pixels tall, and stuffing it into the variable $image. Then we’re defining $white to be a color with the red-green-blue values of 255-255-255, which is white. This becomes the image background color since it was the first color allocated after creating the image. We then define $black as a color with RGB values of 0-0-0, which is black. We’ll use this for our text later.

Now we need a font to work with. While PHP has some built-in fonts, they aren’t all that attractive, and it might be nice to have a font that matches the rest of the images in your layout. Ergo, upload a copy of your favorite TTF and we’ll use that:

1
2
$font_regular = 'Times_New_Roman.ttf';
$size_regular = '12';

This defines $font_regular to be Times_New_Roman.ttf. We also define a font size for later use.

All right, let’s do something with this blank image. imagettftext() is your function for this particular project:

1
2
imagettftext( $image, $size_regular, 0, 5, 15, $black, $font_regular, $text );
?>

The parameters are as follows: the image, font size, angle, distance from left, distance from top, color, font face, and the text. You may wonder why I didn’t set the distances to be 0 and 0; if I had done that, the text would be partially cut off.

So we’re well on our way to having a complete image. There are a few last steps we need to take before it’ll work, though. First is to pass a header notifying the browser that this file is actually an image. Then we need to use imagepng() to convert our image into a PNG file. Then, as clean up, we need to use imagedestroy() to free the memory associated with our image:

1
2
3
header( 'Content-type: Image/PNG' );
imagepng( $image );
imagedestroy( $image );

Now all you need is to pass the title of your entry to image.php. In Wordpress, this might be done like so:

1
2
$url = 'image.php?text=' . urlencode( the_title('', '', false) );
echo '<img src="' . $url . '" alt="Generated image" width="200" height="40" />';

You can find out more about WP’s the_title() function on the Wordpress Codex.

Now if only we could have all the nifty stuff that we can create in The GIMP or Photoshop, with just our dynamic text on top of it. We can using the imagecreatefrom functions, such as imagecreatefrompng().

Choose a base image to use as a background for each of our entry title images. We’ll modify our script from $image = imagecreate( 200, 40 ); to $image = imagecreatefrompng( 'base.png' );.

Adjust the position of the text a little bit, maybe change fonts or your base image, and you could have a really neat entry title that is completely dynamic. You could use this same technique for your entry dates or page titles.

There are lots of other useful functions that PHP provides for your image generation needs, including tools for drawing geometric shapes and creating transparent colors. Visit the Image Functions reference for more information. I also recommend this tutorial for a more general (and thorough) introduction to image generation with PHP.