Skip to the content...

Welcome to the David Walsh Blog. I'm a MooTools, Dojo, jQuery, CSS, and PHP Web Developer located in Madison, Wisconsin, United States. Please contact me if I can make your experience on my website better.

Automatically Generate a Photo Gallery from a Directory of Images: Updated

57 Responses »
PHP Photo Gallery

Two years ago Chris Coyier wrote an outstanding tutorial detailing how you can generate a photo gallery based on the images within two directories: a thumbnails directory and an originals directory. I've decided to take his tutorial a step further by showing you how to generate thumbnails for the gallery using PHP. I've also implemented a MooTools lightbox: Smoothbox. The following code will show you how to create a beautiful photo gallery by simply dumping your photos in a directory.

The CSS

.clear			{ clear:both; }
.photo-link		{ padding:5px; margin:5px; border:1px solid #ccc; display:block; width:200px; float:left; }
.photo-link:hover	{ border-color:#999; }

The images/links will be floated next to each other. The other option would be to use a table. Booooo.

The PHP: Utility Functions

/* function:  generates thumbnail */
function make_thumb($src,$dest,$desired_width) {
	/* read the source image */
	$source_image = imagecreatefromjpeg($src);
	$width = imagesx($source_image);
	$height = imagesy($source_image);
	/* find the "desired height" of this thumbnail, relative to the desired width  */
	$desired_height = floor($height*($desired_width/$width));
	/* create a new, "virtual" image */
	$virtual_image = imagecreatetruecolor($desired_width,$desired_height);
	/* copy source image at a resized size */
	imagecopyresized($virtual_image,$source_image,0,0,0,0,$desired_width,$desired_height,$width,$height);
	/* create the physical thumbnail image to its destination */
	imagejpeg($virtual_image,$dest);
}

/* function:  returns files from dir */
function get_files($images_dir,$exts = array('jpg')) {
	$files = array();
	if($handle = opendir($images_dir)) {
		while(false !== ($file = readdir($handle))) {
			$extension = strtolower(get_file_extension($file));
			if($extension && in_array($extension,$exts)) {
				$files[] = $file;
			}
		}
		closedir($handle);
	}
	return $files;
}

/* function:  returns a file's extension */
function get_file_extension($file_name) {
	return substr(strrchr($file_name,'.'),1);
}

We'll use three utility functions to make the system work: get_files (retrieves all of the files in a given directory), get_file_extension, and make_thumb (generates a thumbnail image from a source image). These are good functions to keep at hand for other purposes too.

The PHP: Setting and HTML Generation

/** settings **/
$images_dir = 'preload-images/';
$thumbs_dir = 'preload-images-thumbs/';
$thumbs_width = 200;
$images_per_row = 3;

/** generate photo gallery **/
$image_files = get_files($images_dir);
if(count($image_files)) {
	$index = 0;
	foreach($image_files as $index=>$file) {
		$index++;
		$thumbnail_image = $thumbs_dir.$file;
		if(!file_exists($thumbnail_image)) {
			$extension = get_file_extension($thumbnail_image);
			if($extension) {
				make_thumb($images_dir.$file,$thumbnail_image,$thumbs_width);
			}
		}
		echo '<a href="',$images_dir.$file,'" class="photo-link smoothbox" rel="gallery"><img src="',$thumbnail_image,'" /></a>';
		if($index % $images_per_row == 0) { echo '<div class="clear"></div>'; }
	}
	echo '<div class="clear"></div>';
}
else {
	echo '<p>There are no images in this gallery.</p>';
}

The first step is to define a few simple settings which will dictate image paths, the width by which all thumbnails will be created, and the number of images per row. The action begins with rounding up all of the files. With every image in the gallery, we check to see if a thumbnail exists. If a thumbnail doesn't exist, we use PHP and the utility function above to generate one. When the thumbnail is generated (or there was one there in the first place), we output the HTML link/image. I've given the A element the "smoothbox" CSS class so that Smoothbox will make the larger image display in the lightbox.

The MooTools JavaScript / Smoothbox

All you need to do is include the JavaScript file. Sweet.

That's it! Have any features you'd like to see added? Let me know!

Discussion

  1. April 6, 2010 @ 9:22 am

    Just a note: it would be wiser to use pathinfo (http://php.net/pathinfo) to get the extension of a file. It would also be nice to use FilterIterator (http://php.net/FilterIterator) along with DirectoryIterator (http://php.net/DirectoryIterator) instead of that boring, inefficient loop in get_files().

  2. santiago quiss
    April 6, 2010 @ 9:53 am

    Another example with Christina Ricci, I’m starting to think you make this tutorials just to post a photo gallery of her… :)

  3. April 6, 2010 @ 9:54 am

    Why don’t you use scandir()?

  4. April 6, 2010 @ 9:55 am

    @Mathias Bynens: My solution is PHP4 compliant, as much as people probably don’t care.

  5. April 6, 2010 @ 10:05 am

    Very cool! Nice automation of PHP.

  6. jamie
    April 6, 2010 @ 11:35 am

    nice article. this gave me an idea for a theme that I was working on. I am going to use this. Thanks.

  7. william rouse
    April 6, 2010 @ 7:51 pm

    Nice article, yeah! I modified it to work with the jQuery fancybox plugin. What would be a valuable addition is to get it to work with other fromats (PNG, GIF,).
    Would you add the code to do that?
    Thanks now!

  8. william rouse
    April 6, 2010 @ 11:57 pm

    Well I had nothing to do tonight so I was able to spend some time to figure out how to add PNG files to a directory and get it to work.

  9. April 7, 2010 @ 4:04 am

    @Mathias – I didn’t know this function. Thanks!
    @David – Good tutorial, best regards!

  10. marc
    April 7, 2010 @ 4:56 am

    I’ve done something similar myself in the past, but with a few added features. For example, a text file “title.txt” inside the folder which contains an album’s title, and reading the EXIF comment (using PHP) for titles / captions etc of the individual images.

  11. April 7, 2010 @ 6:20 am

    detail. I like picture 2 a lot :P nice work!

  12. david
    April 7, 2010 @ 8:12 am

    @William Rouse: And how did you do it? I’m pretty interested in PNG and GIF support too…

  13. April 7, 2010 @ 8:21 am

    I want to say it would be simple. There are only two JPG-specific functions; those would change dynamically. Let me play with this some more.

  14. marc
    April 7, 2010 @ 8:25 am

    To make it support multiple image types, how about using phpThumb() for the thumbnailing? You could then have all it’s options for thumbnailing, i.e. raidus corners, frames etc. etc….

  15. April 7, 2010 @ 8:31 am

    @Marc: PHPThumb is nice but could be overkill — look how small the current thumbnail-generating function is. Adding PNG and GIF support likely wont add much.

  16. william rouse
    April 7, 2010 @ 8:36 am

    There are a few changes to make to get it to work.
    In the index.php file add variable $extension to the call of make_thumbs():
    if($extension) {
    make_thumb($images_dir.$file,$thumbnail_image,$thumbs_width, $thumbs_height, $extension);
    }

    In the galleryUtil.php file change the function get_files to this:
    /* function: returns files from dir */
    function get_files($images_dir,$exts = array(‘jpg’, ‘png’)) {
    $files = array();

    And lastly in the make_thumb function except a new parameter for the extension, and set up two if structures:

    /* function: generates thumbnail */
    function make_thumb($src,$dest,$desired_width, $desired_height, $ext ) {
    /* read the source image */
    if ( $ext == ‘jpg’ || ext == ‘jpeg’ ) {
    $source_image = imagecreatefromjpeg($src);
    }
    if ( $ext == ‘png’ ) {
    $source_image = imagecreatefrompng($src);
    }
    ….

    if ( $ext == ‘jpg’ || ext == ‘jpeg’ ) {
    imagejpeg($virtual_image,$dest);
    }
    if ( $ext == ‘png’ ) {
    imagepng($virtual_image,$dest);
    }

    That’s it.

  17. william rouse
    April 7, 2010 @ 4:15 pm

    @Matěj Grabovský: Would you demonstrate how to rewrite the function using the methods you suggested and are available in PHP5
    Thanks!
    WBR

  18. April 7, 2010 @ 5:03 pm

    @David Walsh: While it is nice to keep things compliant… it is better to actually encourage people to move forward, I am pretty sure they are going to be discontinuing support for it soon…

  19. April 7, 2010 @ 5:04 pm

    @SeanJA: (It being PHP4…)

  20. April 7, 2010 @ 5:05 pm

    @SeanJA: I suppose — I dont’ think it’s that big of a deal.

  21. April 7, 2010 @ 5:05 pm

    @William Rouse: Could you not just use imagecreatefromstring instead?

  22. william rouse
    April 7, 2010 @ 5:51 pm

    I just read the docs on imagecreatefromstring. Please show me how to use it.

  23. justin noel
    April 9, 2010 @ 12:03 am

    I love all the cool gallery features of your solutions and others I’ve come across. However, they all lack one simple thing for me. Captions.

    How could I display captions for your solution?

  24. marc
    April 9, 2010 @ 1:02 am

    @Justin: Use PHP’s exif_read_data to read any EXIF comment in the JPG file, and use this as the caption.

  25. April 9, 2010 @ 11:38 am

    I’ve done a few of these in the past few months (including multi-tiered versions with different sub-directories representing different galleries), and have found PHP’s glob() function to be a real timesaver.

    Obviously, you’ll want to check that all the files in the directory are indeed images, but you already seem to be doing this with your get_file_extension() function.

  26. April 9, 2010 @ 12:10 pm

    Don’t you know glob()? It’s really useful, you could save a lot of lines. :)

  27. April 10, 2010 @ 3:40 am

    @William Rouse: The get_files functions could be rewritten like this: http://gist.github.com/361919

  28. April 10, 2010 @ 3:44 am

    @William Rouse: Sorry, fixed link: http://gist.github.com/361922

  29. william rouse
    April 10, 2010 @ 10:44 pm

    @Matěj Grabovský: Thanks for the code.

  30. April 11, 2010 @ 9:14 pm

    wow impressive work! I was just thinking how to make a photo gallery with some family pictures and this script will do the job. Thanks!

  31. April 14, 2010 @ 5:08 am

    Thks nice article

  32. April 15, 2010 @ 2:09 am

    can you make a package to download, please.

  33. rudy vail
    April 15, 2010 @ 11:44 am

    I agree with Mehdi. This is exactly what I need, but, since I’m a newb, I’m not sure what to do with the three separate code blocks you provide. I would love to have a working package that I could test and edit to fit my needs.
    Thanks for sharing your knowledge, David!

  34. April 16, 2010 @ 9:05 am

    could see the GD library used to generate small images … winning hard disk space
    I say :P

  35. April 19, 2010 @ 9:51 am

    Hey David,

    This is awesome. I was wondering though if we could make this work for a Flickr directory. By this I mean If I uploaded to a specific folder in my Flickr account could i get this to generate the same on my website?

    If so, how? I’m not nearly as tech savvy as you so any help would be epic!

  36. vinnie
    April 23, 2010 @ 7:31 am

    David, my question is not very related to this topic, but I could not find a better place to contact you. I was reading the comments of this website:

    http://css-tricks.com/redirecting-to-a-splash-page-but-only-once-with-cookies/

    and I found your comment there suggesting to use php to set a cookie to show a splash page only once. I’m needing almost the same thing. I want to show an ads banner only once when the first page of the website get loaded.

    Do you mind sharing a simple working example as I’m not that expert with php?

    Thank you in advance.
    PS. I’ll understand if you remove this comment or place it anywhere else.

  37. vinnie
    April 23, 2010 @ 7:33 am

    David, my question is not very related to this topic, but I could not find a better place to contact you. I was reading the comments of this website:

    http://css-tricks.com/redirecting-to-a-splash-page-but-only-once-with-cookies/

    and I found your comment there suggesting to use php to set a cookie to show a splash page only once. I’m needing almost the same thing. I want to show an ads banner only once when the first page of the website get loaded.

    Do you mind sharing a simple working example as I’m not that expert with php?

    Thank you in advance.
    PS. I’ll understand if you remove this comment or place it anywhere else.

  38. April 23, 2010 @ 5:02 pm

    @Vinnie: Posting the same question repeatedly is obviously the way to get help.

  39. vinnie
    April 24, 2010 @ 9:28 am

    @SeanJA: Do you really think it was my intention to post the same question repeatedly? It would be better if you could provide the answer to my question (in case you know the answer) than say what you don’t know.

  40. April 24, 2010 @ 10:13 am

    @Vinnie: It is not really that hard is it?

    On the spash page:

    $spash = isset($_COOKIE['spalsh'])? = false:true;
    if($splash) // show spash page and set cookie
    else // don’t show splash page and continue to the main page

  41. jacob christoffels
    April 26, 2010 @ 4:38 am

    Is there any chance someone makes a download package with a working gallery? I’m more a designer than a developer but with a working demo and a look at the html/php implementation I think I can make it work.
    Thx

  42. dez
    April 30, 2010 @ 10:11 am

    Nice Script, I’m curious as to how the script sorts thumbnails? I can’t seem to figure out how it sorts files and how to make it sort by filename. Any help would be appreciated. Thanks.

  43. May 28, 2010 @ 6:59 am

    Very useful script, thanks! I’m also wondering how to sort the thumbnails; preferably alphabetically. Any suggestions?

  44. May 28, 2010 @ 7:37 am

    @Rob and Dez: Ah, here we go… to sort alphabetically, just do this:

    After the line

    $image_files = get_files($images_dir);

    insert this

    sort($image_files);

  45. frido
    June 24, 2010 @ 6:03 am

    Hey – I have exactly the same problem as Mehdi and Rudy Vail – the code blocks are confusing, and I have a feeling of that something is missing, do I need the code from the previous version? I can’t make it work (a folder with big pictures, which the code will generate thumbs from and make a gallery, without having to make the thumbs-files myself)

    One package with examples would be over-the-top! Nice sharing though :)

    /Frido

  46. derrick
    July 2, 2010 @ 8:26 am

    Is there a way to limit the amout of thumbs coming in?
    What if you had 30 images, and you only wanted 10 images shown at a time with maybe some sort of button that adds 10 more. Is that possible with this?
    thanks,

  47. daniel
    July 6, 2010 @ 2:51 am

    yes, can we somehow adopt this script to autocreate “pages”. It already has a set number of images per LINE, how about a set number of LINES per “page”?

    I could figure out how to hack this if it the “pages” would be straight html, but I’m lacking the experience in PHP and CSS….

  48. ellen
    July 8, 2010 @ 12:16 pm

    using the older version, I want to sort files and, if possible, add captions to the enlarged versions.

    So… for sorting files do I use:

    sort($image_files);

    and if so, where does that go?

    Thanks for any help and advise. (I already have my thumbnails prepared and named.)

  49. July 14, 2010 @ 5:43 pm

    Excellent tutorial, thanks.

    I made a minor change based on a problem I have sometimes, which is getting a bunch of images, and they are too large. I know there are batch conversion programs out there that reduce image size, but I thought I’d try this one. It was very easy to do.

    I added two varialbes in the settings…
    $mid_dir = ‘galleryMidPreload/’;
    $mid_width = 800;

    and added
    $mid_image = $mid_dir.$file;
    if(!file_exists($mid_image)) {
    $extension = get_file_extension($mid_image);
    if($extension) {
    make_thumb($images_dir.$file,$mid_image,$mid_width);
    }
    }

    after the if block that looks almost the same(could be made in to a function to clean up code)

    lastly made a change to

    echo ‘‘;

    notice $mid_image this was the only change to this line.

  50. didier
    July 28, 2010 @ 1:15 pm

    Hi David

    Always smarts examples !

    Is-it possible to extend your example to make it function using urls rather than images in a folder ? (image of a web page given the url)

  51. nobody
    August 6, 2010 @ 1:51 pm

    It took me awhile in figuring it out on how to run this whole package.
    So I wrote a little summary on what I did. (maybe saving others time)

    Here it goes:

    First, create a test folder. (gallery maybe)
    then make sure you have these files:

    gallery.php – see below
    mootools.js
    smoothbox.js
    smoothbox.css
    loading.gif
    create a subfolder named preload-images and put your pictures there
    create an empty subfolder named preload-images-thumbs

    Now for the gallery.php

    /* copy and paste the css here */

    Well, aside from this little trouble I had. It’s a nice piece of work!

  52. nobody
    August 6, 2010 @ 2:02 pm

    Here’s the (missing) gallery.php from above

    <html>
    <head>
    <script type="text/javascript" src="mootools.js"></script>
    <script type="text/javascript" src="smoothbox.js"></script>
    <link rel="stylesheet" href="smoothbox.css" type="text/css"/>
    <style type="text/css">
    /* copy and paste the css here */
    </style>
    </head>
    <body>
    <?php
    // copy and paste all the php codes here
    ?>
    </body>
    </html>

  53. james
    August 6, 2010 @ 7:42 pm

    Is there an asy way to get this to work with subfolders?

    These subfolders would then be the albums (containing various images) in the gallery

  54. August 8, 2010 @ 4:10 pm

    Do you have a sample page to look at – the code in place I mean – so i can see where I’m going wrong.

    I cant seem to get this to work.

  55. warren
    August 10, 2010 @ 4:12 am

    Anyone have a way of create multple galleries from this script?

  56. james
    August 10, 2010 @ 5:11 am

    Found an alternative that supports subfolders
    http://sye.dk/sfpg/

  57. August 10, 2010 @ 3:05 pm

    Thank you – went and got it – looks promising!

Be Heard!

Share your thoughts with fellow developers of all skill levels! I want to hear from you!

Name*:
Email*:
Website:  
Wrap your code with <code> tags, f00!