Welcome back to part two of the Code Gallery Spotlight of the PHP based Photo Gallery called "AutoGallery". Last week, I discussed with you the general idea of the AutoGallery's image management and introduced the constructor used to initialize the variables in the AutoGallery class. This week, I'll take a look at the two functions that the constructor calls after initialization resize() and cleanup() and how they perform the necessary management of the gallery images. Let's start with the resize() function.
1.2 The Resize() function One of the most obvious requirements for a script designed to fulfill the purpose of a photo gallery using thumbnails is of course thumbnail creation. In this week's spotlight, the function that handles all creation of new thumbnails is the resize() member function of the AutoGallery class. The first step in this process is to retrieve a list of all of the Jpeg files stored within the desired directory. This directory, as you may recall from last week, is stored in the $src member variable and was set when the instance of the AutoGallery class was created. Because there is no convenient way in PHP to only retrieve a listing of files that match a certain file mask, the entire contents of the directory must be retrieved through the use of the dir() function as shown: 1.2.1.1 Code Flow
- Declare the
resize() member function - Get the directory listing by calling the
dir() function
function resize() { $d = dir($this->src ); If you have never used the
dir() function before, the return value basically can be considered an instance of a "directory class". This means that, in this case, the variable $d is a PHP object used for accessing directories and adheres to the syntax and rules of all PHP objects. A PHP directory object returned from the
dir() function has a total of three member functions:
read() Read one filename from the directory
rewind() Rewind the directory listing (start reading from the beginning)
close() Close the reference to the directory And also has two member variables:
$handle The handle to the directory object (use with other functions)
$path Contains the full path name of the currently-accessed directory For our purposes, the only member function you'll be interested in is the
read() function, which returns the next filename retrieved from the directory listing or false if there are no more files in the directory. With this information in hand, let's begin the processing of all the files in the desired directory by storing the current filename in the $entry variable. Because the next segment of code is all contained within a while loop, the entire process will repeat itself as many times as necessary until all of the files in the directory have been exhausted. Assuming a valid filename has been retrieved from your directory object, before continuing you'll have to make sure that the file is actually a Jpeg image. This can be accomplished through a simple regular expression to check the extension of the filename for both a .jpg or .jpeg extension.
1.2.1.2 Code Flow
- Begin a while loop and continue as long as the value of $entry is not false
- Set $entry equal to the next filename in the directory through a call to the directory member function
read() - Check the extension of the filename stored in $entry and only continue if the filename ends in .jpeg or .jpg
while($entry=$d->read() ) { if(eregi(".+.jpe?g$", $entry )) { Assuming that there are only JPEG images in the desired directory, the next step will be to check for the existence of a thumbnail image for the graphic. Thumbnails are all stored in a pre-defined directory as set by the $path member variable and have the following format:
_<prefix string><file name> Where
<prefix string> is a unique string defined by the $prefix member variable and
<file name> is the filename as stored in the $entry variable. Before you create a new thumbnail for the current image, it is a good idea to check to see if creating a new thumbnail is even necessary by checking if a thumbnail file with a filename as described above exists. If a thumbnail file does not exist, one will have to be created using the PHP image manipulation functions. The first step in this process is to load the original file into memory by calling the
ImageCreateFromJPEG() function. Once loaded, the width and height of the image can be found through the
imagesx() and
imagesy() functions respectively. Using this information, the new size of the graphic can be determined.
1.2.2 Calculating the size of the thumbnail The size and orientation of the thumbnail image is based on the width and height of the original image. If the image is taller than it is wide, then the height of the new thumbnail will be fixed to a pre-determined height (in our case, 120 pixels) and the width will be re-calculated using the following formula (rounded down):
<new width> = <new height> * <original width> / <original height> Similarly, if the image is wider than it is tall (or if it is as wide as tall) the width is fixed to a pre-determined width and the height is calculated using the following formula (rounded down):
<new height> = <new width> * <original width> / <original height> 1.2.3 Calculating the positioning of the thumbnail Now that you have determined the width and height of the thumbnail, next you must calculate how the thumbnail will be positioned on the border image. This process is simple, and as before it is different depending on the orientation of the image. Let's assume for a moment that your background image is 60 x 60 pixels (a square). If the new thumbnail is taller than it is wide, the image would be positioned so that it's vertical (y axis) component is zero and it's horizontal (x axis) component would be calculated by the following:
<x value> = 60 - (<thumbnail width> / 2) Or, the formula could be more generalized by saying
<x value> = <background width> - (<thumbnail width> / 2) And conversely, if the image was wider than tall, the opposite applies. The only difference is that the horizontal component (the x axis) is now zero and the vertical component is calculated as follows:
<y value> = <background height> - (<thumbnail height> / 2) With these values calculated you now have everything you need to create the new thumbnail image. You can start by loading the background image into memory using the
ImageCreateFromPNG(). Once you have loaded the background image, use the
ImageCopyResized() function to both resize and position a thumbnail version of the original image onto the background PNG image in memory. Finally, the image can be stored with the appropriate filename in the cache directory using the
ImageJPEG() function and the memory being used by the images de-allocated by using the
ImageDestroy() function.
1.2.3.1 Code Flow
- Check for the existence of a thumbnail for the current file (stored in $entry)
- If no thumbnail exists, load the original image into memory and get the width and height of the image
- Calculate the thumbnail width and height
- Calculate the position of the thumbnail on the background image
- Load the Background image and place a resized copy of the original image on the background and save
- De-allocate the resources used by the images
if (!file_exists("{$this->path}/_{$this->prefix}{$entry}")) { $src = ImageCreateFromJPEG("{$d->path}/{$entry}"); $org_h = imagesy($src); $org_w = imagesx($src); if ($org_h > $org_w) { $cfg['height'] = 120; $cfg['width'] = floor ($cfg['height'] * $org_w / $org_h); $cfg['dstX'] = 60 - ($cfg['width'] * 0.5); $cfg['dstY'] = 0; } else { $cfg['width'] = 120; $cfg['height'] = floor ($cfg['width'] * $org_h / $org_w); $cfg['dstX'] = 0; $cfg['dstY'] = 60 - ($cfg['height'] * 0.5); } $img = ImageCreateFromPNG ($this->tpl); ImageCopyResized ($img, $src, $cfg['dstX'], $cfg['dstY], 0, 0, $cfg['width'], $cfg['height], $org_w, $org_h ); ImgeJPEG ($img, "{$this->path}/_{$this->prefix}{$entry}", 90); ImageDestroy ($img); ImageDestroy ($src); Finally, once the image has been created the last step is to update (if necessary) the index file. The index file is nothing more than a simple text file with each line referring to a single image in the gallery and has the following format:
<thumbnail filename> , <origional filename>, <org. width> , <org height> Before you write a new entry to the index, first you have to make sure the filename doesn't already exist in the index. This can be done by loading the entire index into memory using the
file() and
join() functions to create a single string then searching for the existence of the original filename using the
strstr() function. If the original filename does not exist in the index, then the index file must be opened and a new record must be appended to the end of the index file using the
fwrite() function.
1.2.3.2 Code Flow
- Convert the entire index file into a string, then search for the existence of the original filename in the string
- If the original filename does not exist, open the index file using
fopen() and write a new line in the index using fwrite() - Close any file or directory references and return from the function
if (!strstr (join ('', file ("{$this->path}/{$this->idxfile}")), $entry)) { $fp = fopen("{$this->path}/{$this->idxfile}", "a+"); $str = "_{$this->prefix}{$entry}, $entry, $org_w, $org_hn"; fwrite ($fp, $str, strlen($str)); fclose($fp); } // End of index records check } // End of check for previous thumbnail file } // End of check for a file ending in .jp(e)g } // End of While loop $d->close(); } // End of resize() function Article originally published by
Zend, the php company.
John Coggeshall is a PHP consultant and author who started losing sleep
over PHP around five years ago. Lately you'll find him losing sleep
meeting deadlines for books or online columns on a wide range of PHP
topics. He maintains a PHP website packed full of PHP-related materials,
tutorials, projects and more at http://www.coggeshall.org/.
About the author:
| John Coggeshall is a PHP consultant and author who started losing sleep over PHP around five years ago. Lately you'll find him losing sleep meeting deadlines for books or online columns on a wide range of PHP topics. He maintains a PHP website packed full of PHP-related materials, tutorials, projects and more at http://www.coggeshall.org/. | |
Comments
Post new comment