Fun with the PHP GD Library: Part 1

If you’re an avid PHP developer, you are probably aware of the GD library extension. For those who are unfamiliar, the GD library allows you to alter, manipulate, and create images quite simply. Today, we’ll learn the basics of using PHP and the GD library.

First Things First

You will need to make sure the GD library is installed and activated on your server. Don’t know how to do this? No worries, just create a PHP file on your server and type in:

<?php echo phpinfo(); ?>

Now access the page in your browser and you’ll see a giant list detailing the features of your version of PHP. Scroll down a bit and look for the ‘GD’ heading to make sure it is enabled. If it is not, you will need to contact your hosting company. Luckily, most servers I have worked on already have the GD library installed and activated.

If you would like to read more about the GD library, be sure to check out the GD manual introduction.

The Basics

Let’s go over some basics to get us started. Firstly, we will want to make sure we report all errors to the browser. We can do so by entering the following at the very top of our php file:

<?php
ini_set("display_errors", "1");
error_reporting(E_ALL); 
?>

Be Square

Let’s start off simple and use PHP to create a blue square for us – nothing amazing but we need to know the basics first. To achieve our square, we need to do the following:

  • Set our content type as an image so the browser can properly interpret the script.
  • Create a new blank image canvas with a certain width and height.
  • Set our background color to blue.
  • Save the final image and output it to the browser.
  • Clear up any memory used to create and store the image.
  • Call the image from our index.php file to be displayed.

Now that we have our steps and process for the square worked out, we can start to code. I did my best to comment each step of code, and will go through any specific functions or processes after the code snippet. That said, here is the code for our square. Once pasted in, save this file as ‘basic_square.php’:

<?php
//Report any errors
ini_set ("display_errors", "1");
error_reporting(E_ALL);
 
//Set the correct content type 
header('content-type: image/png');
 
//Create our basic image stream 
//125px width, 125px height
$image = imagecreate(125, 125);
 
//Set the background color
$blue = imagecolorallocate($image, 0, 0, 255);
 
//Set up another color just to show how the first color declared is used as the background color when we use imagecreate() 
//Notice how blue is applied to the background, *not* red.
$red = imagecolorallocate($image, 255, 0, 0);
 
//save the image as a png and output 
imagepng($image);
 
//Clear up memory used
imagedestroy($image);
?>

Let’s go through each function and step in the code above so we can better understand what is going on here.

  • As mentioned, we report any errors to the browser so we can fix any bugs.
  • Next we use the header() function to set our content type to a png image.
  • We store the image in a variable named ‘image’ and create our basic image stream and declare our width and height. See imagecreate() for more information.
  • Next up we use the imagecolorallocate function to store the color blue in our ‘blue’ variable. Also notice how the first color declared will be set as the background using imagecreate. So blue will be our background color, not red.
  • We use imagepng() to save our final image, it takes additional parameters if you would like to save it to a directory.
  • Lastly, we clear up the memory used by calling imagedestroy().

We can access and view our blue square by going to blue_square.php, or even better, we can link to it on our index.php like so:

<img src='http://themeforest.s3.amazonaws.com/65_gd/basic_square.php' alt='' />

Assuming all went well, you should see a blue square like the one below:

Hello World

Now that we have the very basics of creating an image, let’s create an image with some text and a font of our choice. We can use any font we wish, as long as the font is a TrueType Font (.tff). For the next few examples I will be using the font ‘Advent’ which you can find here. We will create the string ‘Hello World’ on a dark gray background square. Let’s take a look at the source code first and then go over each step.

<?php
//Report any errors
ini_set("display_errors", "1");
error_reporting(E_ALL); 
 
//Set the content type
header('content-type: image/png');
 
//Create our basic image stream 300x300 pixels
$image = imagecreate(300, 300);
 
//Set up some colors, use a dark gray as the background color
$dark_grey = imagecolorallocate($image, 102, 102, 102);
$white = imagecolorallocate($image, 255, 255, 255);
 
//Set the path to our true type font 
$font_path = 'advent_light';
 
//Set our text string 
$string = 'Hello World!';
 
//Write our text to the existing image.
imagettftext($image, 50, 0, 10, 160, $white, $font_path, $string);
 
//Create our final image 
imagepng($image);
 
//Clear up memory 
imagedestroy($image);
?>

Save the code in a file named ‘hello_world.php’ and access it using the same technique as we mentioned above. So what is different here?

  • We set the dimensions to 300×300 pixels and used a dark grey background.
  • Notice how we declared a variable named font path and used the name of our font as the value? This is because later in our script we need to know the path to our font so we can use PHP to draw our text. Also take careful note of how there is no extension. To quote the manual:
    Depending on which version of the GD library PHP is using, when font file does not begin with a leading / then .ttf will be appended.

    This means since the file to our font does not have a ‘/’ in front of it, .tff will automatically be appended.

  • Next we set our string, ‘Hello World!’, and store it in a variable for later use.
  • The main function to note here is next, imagettftext(), which takes 8 parameters. Resource $image, float $size, float $angle, int $x, int $y, int $color, string $fontfile, string $text (in that order).

Save this page and access it however you wish; you should get an image that looks like the one below.

Angle it!

Did you catch that one of the parameters of the imagettftext function is ‘angle’. This means we can angle our string for some unique results. Let’s revisit our code from above and angle our ‘Hello World!’ text.

<?php
//Report any errors
ini_set("display_errors", "1");
error_reporting(E_ALL); 
 
//Set the content type
header('content-type: image/png');
 
//Create our basic image stream 300x300 pixels
$image = imagecreate(300, 300);
 
//Set up some colors, use a dark gray as the background color
$dark_grey = imagecolorallocate($image, 102, 102, 102);
$white = imagecolorallocate($image, 255, 255, 255);
 
//Set the path to our true type font 
$font_path = 'advent_light';
 
//Set our text string 
$string = 'Hello World!';
 
//Write our text to the existing image.
imagettftext($image, 50, -45, 30, 70, $white, $font_path, $string);
 
//Create our final image 
imagepng($image);
 
//Clear up memory 
imagedestroy($image);
?>

Notice how we have added an angle of -45 degrees to the function instead of zero (as well as reposition our text some)? This is all that is needed to angle some text onto an image; you should see something like the image below.

Are you having fun yet? No? Well, then let’s use a more practical approach and create something that could prove useful.

What’s the Date?

Not only can we create images from scratch, but we can create images from existing images! With a little work we can easily create a small ‘calendar icon’ that displays the current date (month, day, year). A simple Google search for ‘blank calendar icon’ brought up a free .svg icon that I resized and converted to a .png. So you have an idea of what I am talking about you can view the blank ‘calendar below.

Now that we have a canvas to work with, we can use various GD and PHP date functions to make this all come together. Disclaimer: I am not the worlds greatest designer, a better blank icon and choice of fonts would probably be a good idea if I were to be using this ‘calendar icon’ on a real site. I will leave the designing to all of you. That said, let’s look at the final code and then review it.

<?php
//Report all Errors
ini_set("display_errors", "1");
error_reporting(E_ALL); 
 
//Set content type
header('content-type: image/jpeg');
 
//Store the values of our date in separate variables 
list($month, $day, $year) = explode('/', date('F/jS/Y'));
 
//Load our base image 
$image = imagecreatefrompng('calendar_blank.png');
$image_width = imagesx($image);
 
//Setup colors and font file 
$white = imagecolorallocate($image, 255, 255, 255);
$black = imagecolorallocate($image, 0, 0, 0);
$font_path = 'advent_light';
 
//Get the positions of the text string
$pos_month = imagettfbbox(13, 0, $font_path, $month);
$pos_day = imagettfbbox(25, 0, $font_path, $day);
$pos_year = imagettfbbox(8, 0, $font_path, $year);
 
//Create Month
imagettftext($image, 13, 0, ($image_width - $pos_month[2]) / 2, 40, $white, $font_path, $month);
 
//Create Day 
imagettftext($image, 25, 0, ($image_width - $pos_day[2]) / 2, 80, $black, $font_path, $day);
 
//Create Year
imagettftext($image, 8, 0, ($image_width - $pos_year[2]) / 2, 100, $black, $font_path, $year);
 
//Create final image 
imagejpeg($image, '', 100);
 
//Clear up memory;
imagedestroy($image);
?>

So what is going on here? What is this list() function? All good questions, and we will discuss them all step by step:

  • As always we set the header type so the image will display correctly.
  • On line 10 you will see we use the list function. We assign the values of the date array (converted to an array via explode()) to the variables inside the list function. This is a handy way of taking array information and assigning it all at once to multiple variables. We can now access the $month, $day, and $year variable individually.
  • On line 22-24 we use imagettfbbox() function to retrieve the bounding box of our strings (in a nutshell, the size or length), the function returns an array of values, so to access the lower right corner we could use $pos_month[2]. We need this information so we can automatically position our text correctly no matter the size.
  • Lastly we create each string and use some basic math to position the x coordinate of our string.

Assuming the universe did not implode, you should get an image like the one below (except the date should be whatever the current date is on your server, below is a static image of the outcome). Also, thanks to catpin for the help with the script.

Cats and Image Filters

The last thing we will touch on today is the very fun imagefilter() function. The imagefilter function takes a pre defined image and applies a specified filter to the image, such as changing the image to grayscale. Let’s look at the image we will be working with, completely untouched.

Now let’s convert this crazy kitty to a grayscale image using the imagefilter function.

<?php
//Report all errors
ini_set("display_errors", "1");
error_reporting(E_ALL); 
 
//check to see if a source image is set 
if(isset($_GET['source'])){
	//Perform some very basic sanitation of string
	$image = filter_var($_GET['source'], FILTER_SANITIZE_STRING);
 
	//Load image from source provided
	$image = imagecreatefromjpeg($image);
 
	//Change the image to a grayscale image
	imagefilter($image, IMG_FILTER_GRAYSCALE);
 
	//Set content type 
	header('content-type: image/jpeg');
 
	//Save image with 90 percent quality 
	imagejpeg($image, '', 90);
 
	//clear up memory 
	imagedestroy($image);
}
?>

I have made the above script a little more flexible, so as to give you the choice of turning any image into a gray-scale image by referencing it like below:

<img src='http://themeforest.s3.amazonaws.com/65_gd/grayscale.php?source=cat.jpg' alt='' />

Obviously, you could fill in the ’source’ with the path to any image you wish to have it converted to gray-scale. Furthermore, please implement further security measures if you plan on using this on a live server. Also the script above expects to receive a .jpeg image, you can get creative and have it accept all type of images if you wish. Your cat should now look like the image below.

More Filters

To wrap up this lesson, let’s take a quick look at other filters that we could use and the results they produce.

Brightness Filter

Adjusts the brightness of a given image, third parameter adjusts the brightness.

<?php
header('content-type:image/jpeg');
 
$image = imagecreatefromjpeg('cat.jpg');
//3rd parameter accepts the brightness level.
imagefilter($image, IMG_FILTER_BRIGHTNESS, 40);
imagejpeg($image, '', 90);
imagedestroy($image);
?>

Gaussian Blur

Gaussian blurs the image, no parameters accepted.

<?php
header('content-type:image/jpeg');
 
$image = imagecreatefromjpeg('cat.jpg');
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
imagejpeg($image, '', 90);
imagedestroy($image);
?>

Contrast

Third parameter accepts the contrast level.

<?php
header('content-type: image/jpeg');
$image = imagecreatefromjpeg('cat.jpg');
imagefilter($image, IMG_FILTER_CONTRAST, -15);
imagejpeg($image, '', 90);
imagedestroy($image);
?>

Mean Removal (sketch effect)

No parameters accepted.

<?php
header('content-type: image/jpeg');
$image = imagecreatefromjpeg('cat.jpg');
imagefilter($image, IMG_FILTER_MEAN_REMOVAL);
imagejpeg($image, '', 90);
imagedestroy($image);
?>

Colorize

Accepts value of red, green, blue, and alpha channel (optional) in that order.

<?php
header('content-type:image/jpeg');
$image = imagecreatefromjpeg('cat.jpg');
//alpha channel parameter omitted below as it is optional.
imagefilter($image, IMG_FILTER_COLORIZE, 50, 0, 0);
imagejpeg($image, '', 90);
imagedestroy($image);
?>

Until next time…

I hope this gave you some insight to the PHP GD library. In part 2, we will go over some more advanced techniques, and, of course, have some more fun. Get creative with the GD library and let me know what you end up with!



25

Comments
  • M.A.Yoosuf says:

    its cool man, i just went trough, but i wanna try this on week end

  • Allan says:

    wow… thx again for this nice walkthrough… :)

  • David Singer says:

    First line should read: “If you’re an avid PHP developer, you are probably aware that ImageMagick is faster and easier to use than the aging GD library extension which was last updated since 2007.”

    http://us.php.net/imageick

  • AdrianMG says:

    Yeah, kudos for imagemagick :)

  • Great Stuff :D Can’t wait for the next one!

  • Zhuoshi says:

    wow, I didn’t know you could do so much with the GD library.

  • Jarryd says:

    I’ve always wanted to know how to use the GD library :)

  • Bass P says:

    say Drew and all the others from Envato, you guys are doing a great job undoubtedly BUT is it possible to make only a teaser appear in the RSS feed? I get your entire post in my RSS reader (Google Reader) .. it doesn’t make sense.. Do you agree?

  • Ben Durham says:

    I’ve been following all of the video tutorials since Diving Into PHP started, so I also watched you WordPress for Designers series. I love the video tutorials. Would it be possible to convince you to do a video series (or even just a single video) on CSS?

    Keep up the great work!

  • chris simpson says:

    I second the comments about ImageMagick, that said we recently used JPgraph [ http://www.aditus.nu/jpgraph/features.php ] on a project (this is based on GD) and it worked out really well for us.

    FAO: Jeffery: Are there any plans to add threaded comments to this blog?

  • Synook says:

    ImageMagick definitely wins against GD. The only problem is that hardly any hosts support it…

  • Andris says:

    Wow! This is amazing. Looking forward to learn more.

  • Nic says:

    I had used GD before, but these are some awesome examples. In regards to ImageMagick, I used in a project until I realized that the customer’s hosting didn’t have it installed and refused to do so. GD is more readily available.

  • On topic of ImageMagick (anyone else notice they spell it differently in different areas of the php site? u.e. Imagick, Imageick, and ImageMagick) I agree that it rocks and it is slightly easier to use than GD, however I have found most hosts *do not* support ImageMagick by default. Since this is a ‘part 1′ tutorial, I wanted to start with something that most people would have easy and instant access to, as I have found the GD library is installed by default on nearly every host and server I have ever worked on/with. Maybe we will have an ImageMagick series sometime ;)

    @BassP – I’ll pass your suggestion on to Jeffrey, unfortunately, I have no control over any of Envatos RSS feeds and their format :)

    @Everyone – Thanks for the comments and your input!

  • Mike says:

    Very Userfuuuuuuuuuuuuuuuuuuuuuuul THANKS

  • Willabee says:

    This might be of value to others. I wrote up the code and tested it only to receive an error:

    image cannot be displayed, because it contains errors

    After spending an age getting nowhere I commented out the header(‘content-type: image/png’); statement and found the initial output to be:

    ‰PNG  ��� …

    Something was causing unwanted output before PNG.

    I was using Notepad++ and it was saving as utf-8 with BOM by default. I saved it as utf-8 without BOM and all was well. Lesson learnt.

  • Willabee says:

    @Drew – Great intro’ to GD.

    The only other issue I had was having to add the .ttf extension to the font name. It failed otherwise?!!!

  • Great introductory tutorial to GD. Going to need thing on an upcoming project.

  • Good stuff… I have been having trouble inputting font colors though…

    My color picker does fine and sends the hexadecimal color to the PHP page that renders the image using the GD Library… but then the problem starts…

    I have a small routine which converts the hex to RGB, but for some reason, my font then always comes out black…

    Here is my code… any ideas?

  • Maicon says:

    Very good tips! Before read this tut I don’t know that is possible write with GD. Thank you.

  • Anthony says:

    “On topic of ImageMagick (anyone else notice they spell it differently in different areas of the php site? u.e. Imagick, Imageick, and ImageMagick)”

    Imagemagick is the base program and “Imagick is a native php extension to create and modify images using the ImageMagick API.”

    I prefer using the command line but it needs safemode. I beleve Imagick does not need this ( why they called it Imagick I do not know as it causes confusion ). Imagick does not seem to have as much support and I find the command line simpler to use.

    I think before the filters were added in 2007 ? the last time GD was upgraded was 2004?

    One of the problems with Imagemagick is that it is improved/bugs removed very regularly but hosts are not to keen on upgrading it so often. My server version is 6.3.5 which is at least 18 months old. The normal basic version on a lot of hosts is 6.05 which comes with some of the standard Linux installs?

    If you install Imagemagick on your PC you can run it from the command line or through XAMPP WAMP etc. but make sure you install Ghostscript as well if you are going to be working with text : )

    Some nice GD examples and very well explaned.

  • Anthony says:

    Sorry needs Safemode turned off – I fogot the turned off part !

  • N3z@r says:

    Very very very very niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiice !!

  • Anjan Bhowmik says:

    Hi!

    Thats an excellent tutorial for me! It cleared my knowledge with GD library.

    And learned a few coding style!

    I request u to describe “imageconvolution” function, if u can, since it also can create some filters (as i found in php manual)

    Thanks,
    Anjan

  • Wow!! I like this feture php is very good.
    Thanks.