Image Manipulation with PHP - The GD Libraries

The GD libraries are the principle PHP module used for image manipulation, and are available from Boutel.Com, Inc.

If you are lucky enough to be hosted on (or indeed own) a server running GD2.0 or above, you’ll have the ability to use truecolour images in jpeg format (and in png if version 2.0.4+) and therefore, you won’t really benefit by reading this tutorial. Those using GD2.0+ should be opting to use ImageCreateTrueColor in place of ImageCreate, and ImageCopyResampled in place of ImageCopyResized to assure use of maximum colour levels. If you’re running anything under 2.0, read on!

Creating the Image

The function ImageCreate(x_dimension,y_dimension) in GD is restricted to a palette of 256 colours, and as such, it rarely outputs an image at a quality that’s acceptable to most Web designers. Fortunately there is a way of getting around this restriction, and maximizing the palette to 16.7 million colours. To enable this, you’ll need a graphics editor that’s capable of saving jpegs with zero compression, a GD-capable server, and a few spare minutes to read this tutorial.

A quick explanation of the concept…

If you use ImageCreateFromJPEG($image_pointer); your usable palette will exactly mimic that of the image to which you point. So, if we throw away the ImageCreate(width,height) function and focus on trying to use ImageCreateFromJPEG, we should be heading toward a better palette. Those of you who are conversant with GD (or the swifter thinkers among you) might already have noted that creating from a hosted image does not allow us to specify a width and height for the image we’ve created. If our resource image is 400px by 200px, and we want to create a thumbnail wiht a maximum dimension of 100px, then we’ll want a base image of 100px by 50px.

This limits us to two options:

  1. Either we upload base images at all the width-height variations needed by our script, and dictate which one to use through a little basic mathematics, or
  2. We use one image that’s sized to accommodate any dimension we will need, and which will only draw to a designated area of that size, leaving any edges blank/page colour.

If all your displayed images are the same size, you won’t have any major problems to solve — you can simply base your images on a large blank palette that is presized to the dimensions you need. And if you feel like exploring the first option and uploading multiple base images, you should be able to manage with the hints you’ve already picked up here.

The rest of this tutorial will deal with the second option. We’ll look at how to deduce which area of the created image to draw to, and the tips and hints provided here should get you up and running quickly!

Basic Thumbnail Rules

1. Be Kind To Your Server

It’s easy to display a group of thumbnails just by iterating through the images in a directory, and pushing them all through a thumbnailing script. Because it is so easy, some people do exactly that at every page load, which quite obviously is a little server- resource hungry. A much better alternative is to save an actual thumbnail image onto the server and simply display that.

2. Protect your Thumbnailing Scripts

For versatility, you’ll want a few variables that control output of the thumbnail. You’ll need an image pointer at the very least, maybe a switch that allows you to save a copy to the server if need be, and perhaps a compression setting. With those in place, you’ll want to assure that no one can enter a URL that will override your usual settings. The typical options of sessions or .htaccess will do fine.

The Scripts

Currently we’re trying to create a new image that represents another image whose dimensions are not known prior to running the script.

As we discussed, we’ll want to have available a few variables that allow us to specify our resource image, control whether a copy is saved on the server, and control the output compression ratio.

But we can also use a session check to control whether the script is run or not. Perhaps our administration panel could register a session called ‘allow_thumbs‘ to enable the script. We’d call this script using the src attribute of an <img> tag, in a manner similar to this:

<img src="thumb.php?basepath=foldername/   &img_ref=nicebig.jpg&create=yes&compress=65">

Because we will be using exactly the same base image each time, we can also hard code the dimensions into the tag, along with an alt=. You will, no doubt, find your own system for building the calling tag, based on your current administration set up.

Another thing to note about calling through the src of an <img> tag is that any parse errors that occur in the script will not be echoed to the page. All that will happen is that you’ll see an image-not-found space on your page. If you need to see the error returns for debugging purposes, you’ll need to temporarily remove the session protection, and access the script directly through a URL call.

The following script will produce a thumbnail by using a blank base image, rather than the ImageCreate() function. An explanation of the specific syntaxes follows.

session_start();   if($HTTP_SESSION_VARS["allow_thumbs"] == "yes")   {   header ("Content-type: image/jpeg"); 

// define the small, square image that will be    // used as the thumbnail base 

$palette_image = 'foldername/large_palette_base_image.jpg'; 

/****** You shouldn't need to edit below here ******/ 

// Set some defaults values for variables that have not    // been passed to the script through the url 

if(!isset($HTTP_GET_VARS['create']))    {$HTTP_GET_VARS['create'] = 'no';}   if(!isset($HTTP_GET_VARS['basepath']))    {$HTTP_GET_VARS['basepath'] = '';}   if(!isset($HTTP_GET_VARS['compress']))    {$HTTP_GET_VARS['compress'] = 100;} 

// establish where on the thumbnail we can draw to 

$thumbsize = getImageSize($palette_image);   $maxdim = $thumbsize[0];   $draw_from = $HTTP_GET_VARS['basepath'].$HTTP_GET_VARS['img_ref'];   $dim = GetImageSize($draw_from);   if($dim[0]>$dim[1])   {   $to_w = $maxdim;   $to_h = round($dim[1]*($maxdim/$dim[0]));   $to_x = 0;   $to_y = round($maxdim-$to_h)/2;   }   else   {   $to_h = $maxdim;   $to_w = round($dim[0]*($maxdim/$dim[1]));   $to_y = 0;   $to_x = round($maxdim-$to_w)/2;   } 

// create some base images to start designing from    // and make initial basic thumbnail 

if($dim[2]==1) {$from = ImageCreateFromGIF($draw_from);}   elseif($dim[2]==2) {$from = ImageCreateFromJPEG($draw_from);}   elseif($dim[2]==3) {$from = ImageCreateFromPNG($draw_from);}   $thumb = ImageCreateFromJPEG($palette_image);   // $set_bg_colour = ImageColorAllocate($thumb,255,0,0);   // $fill_bg_colour = ImageFill($thumb,0,0,$set_bg_colour);   ImageCopyResized($thumb, $from, $to_x, $to_y, 0,    0, $to_w, $to_h, $dim[0], $dim[1]); 

/******* Image Manipulation Scripting *******/ 

// extra image manipulation can go here 

/***** End Image Manipulation Scripting *****/ 

// output the created thumnbnail onto the calling page    // and, if $create has been set to 'yes', also create    // a copy of the thumbnail on the server 

ImageJPEG($thumb,'',$HTTP_GET_VARS['compress']);   if($HTTP_GET_VARS['create'] == "yes")   {   ImageJPEG($thumb,$HTTP_GET_VARS['basepath'].substr   ($HTTP_GET_VARS['img_ref'],0,   strpos($HTTP_GET_VARS['img_ref'],'.')).'_thumb.jpg',    $HTTP_GET_VARS['compress']);   } 

// destroy all the temporary images used by the    //server while executing this    scriptlet (tidying up) 

ImageDestroy($from);   ImageDestroy($thumb);   }

The script above will take a resource image (referenced by img_ref= in the calling url) and reduce it to a thumbnail that fits centrally within the palette image (the blank image used to extend the palette). The palette indexes on the resultant thumbnail will be increased to a maximum size that mirrors that of the palette image. You might like to copy the above script and refer to it during the following explanations.

Syntax Explanations

Let’s now step through the script, and explore what happens at each point.

  • Session - is simply there for security. You could do session_start(); $allow_thumbs = "yes"; session_register("allow_thumbs"); in your admin page to activate the thumbnailing.

    Alternatively, you could remove the session parts and put the thumbnailing script in a folder with a safeguarding .htaccess file. Either way, just make sure people cannot access the script by typing in the URL.

  • header() - to output to a page or file, a header type must be sent. We chose jpeg due to its compression ability.

  • $palette_image - the path (absolute from root, or relative to this script) and name of the square blank image that is to be used as a thumbnail base. I emphasized "square" because you must use a square image with the above script. To create a nice truecolour image, simply:

    • open your graphics program,
    • make a new square (have I mentioned that it should be square?) image,
    • increase colour depth to maximum (if it isn't already), and
    • save it as a .jpg.

      You might also like to fill it with the same colour as the background of your page before you save. Lastly, upload it and change the value of $palette_image to reference this new file.
    • default values - to avoid always having to pass every variable=value pair through the URL call, we just set some default values for use if the variable isn't set. For instance, if we called an image with img src="thumb.php?img_ref=blat.png", the script would automatically set to create=no, basepath='' and compress=100.
    • establish draw area - using GetImageSize(), we find the height and width of both our resource image, and thumbnail base. We check which is bigger on the resource image (whether it is portrait or landscape) and reduce that to mimic the space available on the thumbnail base. Some reasonably easy mathematics can then be used to deduce the other dimension and the top left pixel of our draw area. We have...

    • $to_h - height of the area to draw to

    • $to_w - width of the area to draw to

    • $to_x - horizontal position of first pixel, counted from the left

    • $to_y - vertical position of first pixel, counted from the top

      • create some images - for GD to do any image manipulations it needs to create a copy of the designated image and work from that. We need it to create two images, the thumbnail base (which we called $thumb), and a copy of the resource image (which we called $from). Our earlier use of GetImageSize on the resource image also yielded an index that holds the filetype. A quick bit of value testing will reveal that we can create our copy of that image -- be it a .gif, .png or .jpg -- which means our script is a bit more versatile now.
      • // $set_bg_colour - if you didn't fill your thumbnail base image with the same colour as your page background, you should un-comment this line and the $fill_bg_colour line. You should insert rgb values into the ImageColorAllocate($thumb, red, green, blue) call to mimic your page colour. You could even pass these in as variables in the calling URL.
      • ImageCopyResized - using all the mathematically deduced values, we use this function to take the entire area of our resource image, shrink it and copy it to the rigidly defined area of our thumbnail base.
      • /* image manipulation scripting */ - if we wanted to perform any further manipulations on our thumbnail, we would do so in this area. Further along in this tutorial are a couple of code snippets that you could plug in here.
      • ImageJPEG - this is the call that outputs an image to the browser.
      • if (create = "yes") - to save a copy of the thumbnail we've created onto the server, we need to use the middle parameter of the ImageJPEG function. We test if our variable create has explicitly been set to "yes" and, if so, we rip apart the resource image name to remove the extension and create a file based upon [that image name]_thumb.jpg.

        Note that you will need the directory that you save your thumbnails into to be chmodded to pretty high permissions. You might also want to put the thumbnails in their own seperate directory, in which case you'll want to amend the path - eg. to $HTTP_GET_VARS['basepath']. 'thumbnail_folder/' .substr($....
      • ImageDestroy - because GD had to create images to work from, we end all manipulation scripts by destroying those temporary images from the server.

        I've tested this script using GD1.6.2 and GD1.8.4, which both performed admirably -- certainly an improvement on the 256 colours allowed in the use of ImageCreate().

        Now we've got the basics, let's take a look at how we can use further image manipulation functions...

        Further Manipulations

        In the prior script, there was an area commented out as /* image manipulation scripting */, which was empty. If we wanted to try a few weird and wonderful effects on our thumbnails, we could add code here, integrating all the variables we defined or deduced earlier.

        An example idea might be to add a shadowed bevel to the thumbnail, perhaps with light colour shading on the top and left, and dark colour shading on the right and base. To give you an idea of the techniques involved, I'll take the shadowed bevel idea and step through it slowly.

        Shadowed Bevel

        A useful function in GD is ImageCopyMerge, as it allows us to merge a part of one image onto our thumbnail. It is especially useful because we can also define an opacity for the merged portion (which to you and me means shading). If we use a short for loop to count how far we are from each edge of the thumbnail, we can also use that incremental number to work out the opacity with which we'll draw our dark and light lines.

        // create a dark image and a light image   
        $dark_shadey = ImageCreate($maxdim,$maxdim);     $nadir = ImageColorAllocate($dark_shadey,0,0,0);     $light_shadey = ImageCreate($maxdim,$maxdim);     $nadir = ImageColorAllocate($light_shadey,255,255,255);   
        // decide how wide we want our edge shading   
        $edge_width = 10;     for($edge_pixel = 0; $edge_pixel < $edge_width; $edge_pixel++)     {   
        // work out the opacity relative to how far from the edge we are   
        $opacity =  100 - (($edge_pixel+1) * (100 / $edge_width));   
        // merge a bit of the light image along the top and left side     // merge a bit of the dark image along the base and right side   
        ImageCopyMerge($thumb,$light_shadey,$to_x+($edge_pixel-1),     $to_y+($edge_pixel-1),0,0,1,$to_h-(2*$edge_pixel),$opacity);     ImageCopyMerge($thumb,$light_shadey,$to_x+($edge_pixel-1),     $to_y+($edge_pixel-1),0,0,$to_w-(2*$edge_pixel),1,$opacity);     ImageCopyMerge($thumb,$dark_shadey,$to_x+($to_w-($edge_pixel+1)),     $to_y+$edge_pixel,0,0,1,$to_h-(2*$edge_pixel),$opacity-20);     ImageCopyMerge($thumb,$dark_shadey,$to_x+$edge_pixel,$to_y+     ($to_h-($edge_pixel+1)),0,0,$to_w-(2*$edge_pixel),1,$opacity-20);     }   
        // destroy the two new images that we used   
        ImageDestroy($dark_shadey);     ImageDestroy($light_shadey);

        You might notice I've used a few weird syntaxes here, such as reducing the dark image opacity by 20 in the ImageCopyMerge calls. This is simply because the resultant image looks better if the dark isn't quite as dark as the light is light. If you decide to code your own manipulations, you will (more than likely) have to add a few workaround syntaxes like this to your own scripts.

        Just to keep you going, here are a couple more manipulations that can be cut and pasted into the /* image manipulation scripting */ area of the main tutorial script.

        Spider's Web

        This small plugin scriptlets produces a spider's web effect, which is drawn over the thumbnail in the colour defined as $zenith. This script simply draws a few lines from the lower left corner at various angles, and then draws elliptical arcs centred at the same corner.

        $zenith = ImageColorAllocate($thumb,255,255,255);     for($draw = 0;$draw<$to_h;$draw+=12)     {     ImageLine($thumb,$to_x,($to_h+$to_y),($to_w+$to_x),     (($to_h-$draw)+$to_y),$zenith);     }     for($draw = 0;$draw<$to_w;$draw+=12)     {     ImageLine($thumb,$to_x,($to_h+$to_y),($draw+$to_x),     $to_y,$zenith);     }     for($draw = 1;$draw<14;$draw++)     {     ImageArc($thumb,$to_x,($to_h+$to_y),$draw*($to_w/4),$draw*     ($to_h/4),270,0,$zenith);     }


        This larger plugin scriptlet produces an elliptical shaded doughnut thumbnail. The background and shading colour is defined by $zenith. This manipualtion works by iterating through the thumbnail one pixel at a time, and deciding exactly how much opacity to apply when merging a small dot at that place.

        $dot = ImageCreate(1,1);     $zenith = ImageColorAllocate($dot,255,255,255);   
        for($ypos=0;$ypos<$to_h;$ypos++)     {     for($xpos=0;$xpos<$to_w;$xpos++)     {     $xdist = abs(($to_w/2)-$xpos);     if($xdist==0) {$xdist = 0.01;}     $ydist = abs(($to_h/2)-$ypos);     $dist = sqrt(pow($xdist,2)+pow($ydist,2));     $angl = atan($ydist/$xdist);     $el_dist =      sqrt(pow(abs(cos($angl)*$to_w/2),2)+pow(abs(sin($angl)*$to_h/2),2));     if($dist>$el_dist || $dist<$el_dist/6)     {     ImageCopyMerge($thumb,$dot,$xpos+$to_x,$ypos+$to_y,0,0,1,1,100);     }     else {     $dnut_dist = ($el_dist/12)*5;     $offset_dist = abs((($el_dist/12)*7)-$dist);     $uppy = sin(acos($offset_dist/$dnut_dist))*$dnut_dist;     $opac = 100-((100/$dnut_dist)*$uppy);     ImageCopyMerge($thumb,$dot,$xpos+$to_x,$ypos+$to_y,0,0,1,1,$opac);     }     }     }     ImageDestroy($dot);

        I hope that tutorial and the extra little scriptlets have taught you how versatile the GD libraries can be. Perhaps you have even caught the image-manipualtion bug and are eager to start coding your own transformations! Good luck.

  • Replay

    Category: programming Time: 2002-11-25 Views: 3

    Related post

    • Image Manipulation with HTML5 Canvas: A Sliding Puzzle 2012-01-14

      HTML5 includes many features to integrate multimedia natively into web pages. Among these features is the canvas element, a blank slate that can be filled with line drawings, image files, or animations. In this tutorial, I'm going to demonstrate HTML

    • Image manipulations with category images 2013-01-21

      Is it possible to use image manipulations with category images? I have heard conflicting reports and it's not working for me. There is a spot to designate image manipulations for category images, but it does not work to reference {category_image:medi

    • how to create new image size with new image style with php code in drupal 7? 2012-10-26

      I want to create a new image style in Drupal 7, with a name like front_video_thumbnail. I want to use this size image on front page. I wrote code in template.php preprocess_page(), like the following one. $img = theme('image_style', array('style_name

    • Image manipulation: What are the options? 2011-05-12

      What manipulations on imported images can be done from inside LaTeX? Using the graphicx package, I can Change image width and height Rotate image by a given angle Crop image Select specific page in image file (e.g., in a multi-page PDF) Are the other

    • Simplified Image Resizing with PHP 2003-04-17

      If you're anything like me, you're probably lazy (and if you're not, give yourself a pat on the back!). Recently, as I built a Website to show off a range of products, I realized that not only was I going to want to use the same product image over an

    • ColdFusion 9 at Your Service: Image Manipulation with AIR 2009-10-29

      Earlier this month, Adobe released the latest version of ColdFusion at the MAX conference in Los Angeles. Back in July I gave an overview of ColdFusion 9, covering some of the new features with the benefit of Kay Smoljak's examples. This article is a

    • Image Caching with PHP 2016-02-14

      i am trying to learn how to cache an image that is created in PHP, this current piece of PHP wil cache text to a file, but i want to get it to cache an image called 'my_barcode.png' to the cache folder, any help would be greatly appreciated. <?php $h

    • Does Assets allow you to use the built in Image Manipulations to resize on upload 2013-07-20

      I really want to use the built in Image Manipulations to allow the images to be resized at the time of upload to help remove some of the extra server stress on load in the templates using CE Image. The idea is to create a few sizes small/medium/large

    • Google Image search in Php 2016-01-23

      I'm trying to use google images api with PHP, and I'm really not sure what to do. I have written the following Code <?php $url = "". "v=1.0&q=indian%20institue%20of%20techology&

    • Loading JavaScript libraries with PHP API 2012-10-31

      I have written the following script which simply: Loops through JavaScript files (either defined in a particular package, or separately with the libraries array) Reads the files into the script and combines them into one string Minifies the string an

    • How do I download files of big sizes from somewhere on the web to the web server with PHP? 2009-09-18

      How do I download files of big sizes from somewhere on the web to the web server with PHP? Also, what should be allowed on the server in order to make this happen? Thanks. --------------Solutions------------- You need CURL module installed on PHP. Th

    • How to replace the twentyten image header with my flash banner? 2011-03-26

      I am currently building a site using a child theme for the first time. Basically, I have a flash banner the client has already had made, and want to replace the twentyten image banner with the flash. I know how to do this by editing the header.php (I

    • Programming for the Arduino without the Arduino IDE.. but with the provided libraries? 2012-03-21

      I recently started a new project using my Arduino that's been collecting dust for a while. Along with the physical board collecting dust, so has my copy of avr-gcc and the Arduino libraries. I can manage updating avr-gcc, but I can't remember how I c

    • Access the Windows Registry with PHP 2012-09-10

      Have you ever woken up in the morning and thought to yourself, "I want to do something crazy today?" Well, if today was one of those mornings then you're in luck. I'd like to give you a little introduction on accessing the Windows Registry using

    • Page loads all pages of the image gallery with pagination 2014-02-19

      Same as my previous question I have moved to new website. Here there is a page which contains an image gallery with pagination. The text code is like this: [gallery columns="6" ids="318,319,320,321,322,323,324,325,326,327,328,329,330,331,33

    • Are the TikZ libraries cd and external incompatible with one another? 2014-04-16

      Is there a way to use the TikZ libraries cd and external together? This does not work: \documentclass{article} \usepackage{tikz} \usetikzlibrary{cd, external} \tikzexternalize \begin{document} \begin{tikzcd} A \arrow[rd] \arrow[r, "\varphi"] &am

    • Image manipulation PHP class using PHP's Image Functions 2014-11-14

      I am working on an image manipulation class for a project to re-size uploaded slider images to 780 X 397 and uploaded avatar pictures to 220 X 220. I am wondering if this is a good way to construct it. What would be the best way to handle an image th

    • Re-introducing Vagrant: The Right Way to Start with PHP 2015-06-07

      I often get asked to recommend beginner resources for people new to PHP. And, it's true, we don't have many truly newbie friendly ones. I'd like to change that by first talking about the basics of environment configuration. In this post, you'll learn

    • Conquering Instagram with PHP and the Instagram API 2015-09-18

      Instagram's API allows us to interact with data such as user info, media (photos and videos), likes, comments, and tags. For example, you can search for media around a specific location and filter the results by time. The API also allows us to post c

    iOS development

    Android development

    Python development

    JAVA development

    Development language

    PHP development

    Ruby development


    Front-end development


    development tools

    Open Platform

    Javascript development

    .NET development

    cloud computing


    Copyright (C), All Rights Reserved.

    processed in 5.068 (s). 13 q(s)