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, my friend. 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:
PHP
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:
PHP
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:
PHP
$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:
PHP
$size_regular = '12';
This defines $font_regular to be Times_New_Roman.ttf. We also define a font size for later use.
All right already, let's do something with this blank image. imagettftext() is your function du jour for this particular project:
PHP
?>
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:
PHP
Now all you need is to pass the title of your entry to image.php. In Wordpress, this might be done like so:
PHP
You can find out more about WP's the_title() function on the Wordpress Codex.
Try our script so far. That's really nice, of course, but if our generated image is going to be that dull, what's the point of having an image at all? 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... But wait! PHP is awesome like that, so we can using the imagecreatefrom*() functions, such as imagecreatefrompng().
Let's start with the following base image:
![]()
We'll use that as a background for each of our entry title images.
We'll modify our script from
PHP
to
PHP
Now try it. Adjust the position of the text a little bit, maybe change fonts or your base image, and you could have a really snazzy entry title that is completely dynamic. Don't stop there, either: you could use this same technique for your entry dates, page titles, or even your entries themselves, if you were crazy.
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.
5 Comments
header( ‘Content-type: Image/PNG’ );
imagepng( $image );
imagedestroy( $image );
The code above, where should I place it in image.php?
That you’ll put after you’ve done all your configuration for the image, because those lines are what actually render the image in the browser.
If I might ask this considering I know nothing about php. What is the safety of using a $_Get function?
Anna: it’s the only way I know of to get parameters from the URL. Any input you get from the user should not be trusted, so any data you get from $_GET should also not be trusted. However, you can do things to ensure the data is valid and safe. For example, say you expect the value of $_GET['option'] to be 1, 2, or 3. Something like this would suffice:
if ($_GET['option'] == 1 || $_GET['option'] == 2 || $_GET['option'] == 3)echo 'Yay!';elseecho 'Bad data!';You can also use functions like stripslashes, htmlentities, and mysql_real_escape_string.
How to save a copy of a php generated image ?