PHP Thumbnail Image Gallery Script

Description

  • This is an image gallery script that allows you to simply upload new full sized images in FTP and the script will automatically create the thumbnails for those images and add those images to a paged thumbnail gallery suitable for browsing.

Example

Download

Terms of Use

  • Version 1.2.0 and onward is released under GNU General Public License. Basically this means you are free to use the script, modify it, and even redistribute versions of your own under the same license.

What's new

  • 1.2.1 [January 13, 2008] - Code went through another cleanup and comment updates. Goal is to make it so anyone can easily modify it themselves.
  • 1.2.0 [December 26, 2007]
    1. Stripped out broken Imagemagick support.
    2. Cleaned up the code.
    3. Better commented everything.
    4. Redid the gallery layout to use CSS the user can easily change.
    5. Changed the License to GNU General Public License.
  • 1.1.0 [June 2, 2006] - Started cleaning up the code. This version was never publicly released
  • 1.01 [May 11, 2004] - Initial release

Instructions

gallery.php settings

  • Open gallery.php and scroll down to about line 30 and look for $config['size']. Set this to the maximum width or height you want your image thumbnail to be.
  • On the next line in the $config['imagequality'] set this to the JPEG quality you would like your thumbnails to be. I recommend you keep it set to 70
  • $config['rows'] and $config['cols'] are the number of rows and number of columns of thumbnail images you want shown on each page
  • $config['maxShow'] is the number of page numbers to show at one time. for instance if you have 100 pages of images, you can set this to only show the page numbers of the 10 pages close to where you currently are
  • $config['fulls'] is the relative path to the full size images located on your server. Include the trailing slash. example: $config['fulls'] = "photos/";
  • $config['thumbs'] is the relative path to where you want the thumbnail images to be stored. Include the trailing slash.

File Permissions

  • You'll need to change the permission on the directory you set $config['thumbs'] to. CHMOD it to 775 or 777 so PHP and GD2 can automatically write and create your thumbnails in that directory.

Changing the Look

  • The entire gallery table is controlled by the CSS settings you'll find toward the bottom of the gallery.php file. I tried to comment each specific part of the CSS and what it controls so you can easily change the look of the gallery without actually having to actually edit any of the PHP.

Lightbox

Lightbox Support (OPTIONAL)

  • I've had multiple people want to know how to make this gallery work with the Lighbox script or telling me that they modified it (which is great!) themselves. While the above gallery script does not come with Lightbox support, modifing it to work with Lightbox requires very minor changes.
  • In gallery.php edit line 116 to add rel="lightbox" so it becomes echo '<a href="'. $config['fulls'].$imagelist[$i] .'" title="'. $imagelist[$i] .'" rel="lightbox" target="_blank">';
  • Go down to about line 353 and include lightbox.js and its CSS in the page header (it's normal HTML down there).

Comments

the gallery is great but the vertical images get rotated in the thumbnails. Is there a way to prevent this?

Modern cameras often save all images in landscape (horizontal) mode. When taking a portrait (vertical) picture, the camera still saves the picture in landscape mode but it will add an EXIF tag that identifies the orientation of the picture.

PHP's GD2 library does not read that orientation EXIF tag so you end up with a landscape thumbnail that represents the actual image.

There is likely a way to either (1) read the tag and correctly adjust the thumbnail, or (2) rewrite the necessary tag into the thumbnail using PHP. However, that addition is beyond the amount of time I want to donate into a project I no longer use myself.

Here is the solution for the "not properly rotated thumbnails":

[root@www gal]# diff gallery.php index.php
183a189,217
>       $exif = exif_read_data($fullFilename);
>       $ort  = $exif['Orientation'];
>       $deg    = 0;
>       switch ($ort) {
>       case 2:
>               $mirror = true;
>               break;
>       case 3:
>               $deg = 180;
>               break;
>       case 4:
>               $deg = 180;
>               $mirror = true;
>               break;
>       case 5:
>               $deg = 270;
>               $mirror = true;
>               break;
>       case 6:
>               $deg = 270;
>               break;
>       case 7:
>               $deg = 90;
>               $mirror = true;
>               break;
>       case 8:
>               $deg = 90;
>               break;
>       }
205a240
>               if ($deg) $im2 = imagerotate($im2, $deg, 0);

for those who don't read diff output here's the whole function they need to replace

# returns: true if image created, false if failed
function ResizeImageUsingGD($fullFilename, $thumbFilename, $size) {
        $exif = exif_read_data($fullFilename);
        $ort  = $exif['Orientation'];
        $deg    = 0;
        switch ($ort) {
        case 2:
                $mirror = true;
                break;
        case 3:
                $deg = 180;
                break;
        case 4:
                $deg = 180;
                $mirror = true;
                break;
        case 5:
                $deg = 270;
                $mirror = true;
                break;
        case 6:
                $deg = 270;
                break;
        case 7:
                $deg = 90;
                $mirror = true;
                break;
        case 8:
                $deg = 90;
                break;
        }

        list ($width,$height,$type) = GetImageSize($fullFilename);

        if($im = ReadImageFromFile($fullFilename,$type)){
                //if image is smaller than the $size, show the original
                if($height <= $size && $width <= $size){
                        $newheight=$height;
                        $newwidth=$width;
                }
                //if image height is larger, height=$size, then calc width
                else if($height > $width){
                        $newheight=$size;
                        $newwidth=round($width / ($height/$size));
                }
                //if image width is larger, width=$size, then calc height
                else{
                        $newwidth=$size;
                        $newheight=round($height / ($width/$size));
                }

                $im2=ImageCreateTrueColor($newwidth,$newheight);
                ImageCopyResampled($im2,$im,0,0,0,0,$newwidth,$newheight,$width,$height);
                if ($deg) $im2 = imagerotate($im2, $deg, 0);

                return WriteImageToFile($im2,$thumbFilename,$type);
        }

        return false;
}#-#ResizeImageUsingGD()

Good addition. I really appreciate you sharing your changes.

After adding more photos I ran into the following issue where memory has run out. See the error below. Is this customizable in the script?

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 17152 bytes) in /home/domains/stgrard/public_html/gallery.php on line 244

You are hitting the RAM limit that PHP is allowed to use for your server. Most likely because PHP is trying to process an image too large in size for it to load into memory and create a thumbnail. Some hosts allow you to overwrite this limit. At the top of the PHP file that is having problems, putting:
ini_set("memory_limit","128M"); might work. You can also try creating a /public_html/php.ini file with this value:
memory_limit = 128M
If that doesn't work, try creating a /public_html/.htaccess file with this value (if that file already exists, just add this line to it):
php_value memory_limit 128M

If none of those work, you'll need to either manually create the thumbnail and upload it to your thumbnail directory, or resize the original down to something smaller that the script can handle (this might be a good idea anyway so a visitor doesn't spend too long loading any full sized images).

Currently I'm using the gallery.php file and PHP Thumbnail script version 1.2. I want to change the order to which each JPG file is loaded with the newest on Page 1 and the oldest on Page 100 etc. Is there any way to modify the gallery.php file to do this.

In PHP, that requires reading each file for the timestamp. You can make that happen by editing the GetFileList() function and changing it to:

<?php
#-#############################################
# desc: gets the list of image files in the directory
# param: [optional] directory to look through
# returns: array with timestamp sorted list of images (newest first)
function GetFileList($dirname="."){
    global
$config;
   
$tlist = array();

    if (
$handle = opendir($dirname)) {
        while (
false !== ($file = readdir($handle))) {
           
//this matches what type of files to get. jpeg, jpg, gif, png (ignoring case)
           
if (preg_match("/\.(jpe?g|gif|png)$/i",$file)) {
               
$tlist[$file]=filemtime($dirname.$file);
            }
        }
       
closedir($handle);
    }

   
arsort($tlist);
   
$list=array_keys($tlist);

    return
$list;
}
#-#GetFileList()
?>

If you want to keep the current page listings, but add a "Show All" link, look for the line:
$imagelist = GetFileList($config['fulls']);and under it add:
if(!empty($_GET['showall']) && count($imagelist)>0) $config['rows'] = ceil(count($imagelist)/$config['rows']);

Then in your HTML, add your link to show all:
<a href="gallery.php?showall=true">Show All</a>

You can create cropped thumbnail images by replacing the ResizeImageUsingGD() function with this one:

<?php
#-#############################################
# desc: resize and crop image using GD library
# param: ($fullFilename) filename of full size image ($thumbFilename) filename to save thumbnail as ($size) max width or height to resize to
# returns: true if image created, false if failed
function ResizeImageUsingGD($fullFilename, $thumbFilename, $size) {

    list (
$width,$height,$type) = GetImageSize($fullFilename);

    if(
$im = ReadImageFromFile($fullFilename,$type)){
       
//new is wider than old
       
if(($height/$width) > 1){
           
$cropH=(($height/$size)*$size);
           
$cropW=$width;
        }
       
//new is narrower than old
       
elseif(($width/$height)>1){
           
$cropH=$height;
           
$cropW=(($height/$size)*$size);
        }
       
// same ratio as old. just resize
       
else{
           
$cropW=$size;
           
$cropH=$size;
        }

       
$im2=ImageCreateTrueColor($size,$size);
       
ImageCopyResampled($im2,$im,0,0,0,0,$size,$size,$cropW,$cropH);

        return
WriteImageToFile($im2,$thumbFilename,$type);
    }

    return
false;
}
#-#ResizeImageUsingGD()
?>

Note that if the thumbnails already exist, you'll need to delete them first so they can be recreated at 120x120.

I'm using your script as thumbnails creator for my webcam images. My webcam shoots a photo every 3 minutes and then store all the photos in a folder where I use your script to create thumbnails. Every 24 hours the photos are overwritten with the same image name. Problem is that for the first 24 hours thumbnails match the real photos, while after 24 hours all the photos you see in thumbnails are the old one while if you click on it it shows the real updated one. Is there a way to have all the thumbnails always updated with the last photos shot?

You'll need to add a check and see if the full sized image is newer than the thumbnail. Replace:

// create thumb if not exist
if(!$thumb_exists){
With:
// create thumb if not exist or fullsize is newer
if(!$thumb_exists || filemtime($thumb_image)<filemtime($config['fulls'].$imagelist[$i])){

Nice script, but is it also possible to show the filename under each thumbnail?

You can show the file name under the thumbnail by changing the line:
echo '<img src="'. $config['thumbs'].$imagelist[$i] .'" alt="'. $imagelist[$i] .'">';to
echo '<img src="'. $config['thumbs'].$imagelist[$i] .'" alt="'. $imagelist[$i] .'"><br/>'.$imagelist[$i];

I added the HTML to display the image name, worked great, thanks! How would I also include the dimensions of the full size image under each thumbnail?

Above:
$imagelist[$i] = rawurlencode($imagelist[$i]); add getimagesize() so it looks like this:

$image_size = @getimagesize($config['fulls'].$imagelist[$i]);
$imagelist[$i] = rawurlencode($imagelist[$i]);

And then you can display the size by adding this where you need it:
$image_size[0].'x'.$image_size[1]

I have my images folder with about 100 images in there from my iPhone. All named "IMG_####.JPG". It was only showing the first 3 images and no pagination. I removed one of the images shown, and it now only shows 2 images.
Is there a problem with the filenames?
Also I'm not familiar with the "Oops()" function...?

It should be able to handle "IMG_####.JPG" filenames just fine. The Oops() function is there to print an error message to the page if it identifies a problem.

My best guess is that if the images are huge, it may be running PHP out of its allowed memory when trying to create a thumbnail. Try adding this line to the very top of the script and rerunning it:

<?php
// Report all PHP errors
error_reporting(-1);
?>

Yeah they were huge! I had some panoramic photos in there that were stopping the script. Removed them and it runs just fine! Thanks for a great script!! :)