Article

Home » Server-side Coding » PHP & MySQL Tutorials » Image Manipulation with PHP - The GD Libraries

About the Author

Mark Douglas

author_mark? Mark is a relative newcomer to serverside programming, though he's already showing competence - especially in the area of image manipulation. His recent acquisition, teckis.com is planned as a portal for distributing PHP snippet codes and possibly some complete systems as well.

View all articles by Mark Douglas...

Image Manipulation with PHP - The GD Libraries

By Mark Douglas

November 25th, 2002

Reader Rating: 7.5

Page: 1 2 3 Next

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.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links