Yesterday I promoted a dynamic badge I created for America Held Hostage. Today I’m going to explain how I went about creating this badge.
First, I designed my badge in Photoshop:
Couldn’t I have just used PHP to create this image? Well, of course I could have. But that wouldn’t be a responsible use for resources either system or development. The essentials of the badge won’t change and making it all dynamic is silly.
Now that we have the badge, we simply want to add text to it using PHP. In this case, we’re going to add a countdown till January 20, 2009.
First, we need to tell PHP to send the output of this document in the PNG file format. If you skip this step, you’ll simply see a text dump of the PNG. Not very useful.
<?php Header ("Content-type: image/png");
Next, I declare some variables:
$amount = date("U", mktime(8, 0, 0, 1, 20, 2009)) - date("U"); $days = floor($amount / 86400); $badge_image = imagecreatefrompng("./badge.png"); $text_colour = imagecolorallocate( $badge_image, 255, 255, 255 );
$amount contains the number of seconds until the future date. (“U” gets the number of seconds since the Unix epoch)
$days is that number divided by the number of seconds in a day (86400) and rounded down using floor.
$badge_image holds the image we are going to edit. imagecreatefrompng is the PHP function to create a new image from another image.
$text_colour holds the color of the text to be added.
ImageString is the function PHP’s GD library uses to add text to an image. This works great if you know the exact coordinates you want to add the image. It does not have a built in way to determine the center of an image or similar. Rather than calculating this value (which isn’t as easy as it might seem…you have to take into account the size of the text itself), I used a function someone else wrote that implements ImageString called ImageStringCenter. I found this in the comments of the actual imagestring function. There are actually several versions you can use. The original function centered the string both horizontally and vertically. I modified it to center only horizontally and named the resulting function ImageStringCenterX:
function ImageStringCenterX($image_resource, $y, $font_size, $text, $color ) { $center_x = ceil( ( imagesx($image_resource) - ( ImageFontWidth($font_size) * strlen($text) ) ) / 2 ); $center_y = $y; ImageString($image_resource, $font_size, $center_x, $center_y, $text, $color ); }
As you can see, it takes an image resource (ours is called $badge_image), a Y value, a font size, the text to be added, and the color of the text to be added ($text_colour). It calculates the proper X value and uses the original ImageString function to place the text.
Finally, we add the text to the image.
ImageStringCenter($badge_image, 25, 6, "In ".$days." days", $text_colour); imagepng($badge_image); imagedestroy($badge_image); ?>
ImageStringCenter, as previously discussed, adds the text to the image.
imagepng creates the png.
And imagedestroy cleans up.
It’s that simple.
This is a good explanation of how to edit an image in PHP, but what about creation? Creating an image is as simple as declaring $badge_image was in the above code. You would simply use something like:
$im = imagecreate(100, 30);
It’s as simple as that. You now have an image resource, $im which holds a new 100×30 pixel image.
You can set the background color of this image using the following:
$bg = imagecolorallocate($im, 255, 255, 255);
This sets the images background to the RGB value of 255,255,255. Or, in other words, white.
For more information on creating images in PHP, I recommend you look through PHP’s GD function list. Most of them are self-explanatory and you’ll be surprised at how easily they can be implemented.
The full PHP script:
<?php Header ("Content-type: image/png"); $amount = date("U", mktime(8, 0, 0, 1, 20, 2009)) - date("U"); $days = floor($amount / 86400); $badge_image = imagecreatefrompng("./badge.png"); $text_colour = imagecolorallocate( $badge_image, 255, 255, 255 ); function ImageStringCenterX($image_resource, $y, $font_size, $text, $color ) { $center_x = ceil( ( imagesx($image_resource) - ( ImageFontWidth($font_size) * strlen($text) ) ) / 2 ); $center_y = $y; ImageString($image_resource, $font_size, $center_x, $center_y, $text, $color ); } ImageStringCenterX($badge_image, 25, 6, "In ".$days." days", $text_colour); imagepng($badge_image); imagedestroy($badge_image); ?>
#1 by Nick Johnson at November 26th, 2008
I’m getting a strange error. Using your exact code and image, I keep getting this error message saying that it can’t display the images because it contains errors. It’s not in CMYK, I have no Skype extension installed so I’m not sure what could be causing this error. It won’t display in Firefox 3, Opera or Safari. Could you help me out?
#2 by Nick Johnson at November 26th, 2008
Nevermind, I figured it out.