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

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!


Comments

  1. Matěj Grabovský

    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

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

  3. Mathias Bynens

    Why don’t you use scandir()?

  4. David Walsh

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

  5. Matthew J

    Very cool! Nice automation of PHP.

  6. jamie

    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

    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

    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. Paweł P.

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

  10. Marc

    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. Tampert

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

  12. David

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

  13. David Walsh

    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

    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. David Walsh

    @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

    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

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

  18. SeanJA

    @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. SeanJA

    @SeanJA: (It being PHP4…)

  20. David Walsh

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

  21. SeanJA

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

  22. William Rouse

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

  23. Justin Noel

    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

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

  25. Steve Grunwell

    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. Joffrey

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

  27. Matěj Grabovský

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

  28. Matěj Grabovský

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

  29. William Rouse

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

  30. ken

    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. Fr3do

    Thks nice article

  32. Mehdi

    can you make a package to download, please.

  33. Rudy Vail

    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. Jhon Doe

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

  35. William Garrison

    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

    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

    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. SeanJA

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

  39. Vinnie

    @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. SeanJA

    @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

    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

    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. Rob

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

  44. Rob

    @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

    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

    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

    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

    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. Paul

    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

    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)

    • Didier

      Hi

      For your info I use the well known IEcapt.exe to create images of web pages given an url …

      Even if you need to add some threads to avoid the freeze of your program during the creation of picture, it gives good results … results can be seen here at http://www.saepe.ch

      Do you use it too ?

      PS : thks again to David who is inspiring a lot !

  51. Nobody

    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

    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

    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. Daryl Isaacs

    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

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

  56. James

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

  57. Daryl

    Thank you – went and got it – looks promising!

  58. Ken

    I really like this automated script and improvement on adding auto thumbnails.
    The one change I would like it that the longest side of the thumbnail is a fixed size and the shorter length is in appropriate perspective.
    That way the thumbnails are in a square box no matter whether vertical or horizontal.
    Will look better that fixed with only.
    How do I script that?
    Also, how would I use FancyBox? Much prefer it’s look over MooTools SmoothBox?
    Thanks for help

    • Mads Petersen

      I ust tried to do the same thing as I hear you saying Ken..

      Now i just changed width=”100″ height=”100″ to maxwidth=”100″ maxheight=”100″ in index.php

      Now it made the thumbs display with the right proportions, like I wanted.. But now the way the pictures are displayed all together, is messed up..

      Teck it out:
      http://artscreen.dk/selection/index.php

      Help appreciated

      Cheers,
      Mads

    • Ken Shaw

      can you provide a copy of your full script?
      that way I can see where you made the changes with maxwidth/maxheight
      You are almost there and I want to tinker too but not being a programmer it is a lengthy struggle.
      I see you got it working with fancybox instead of smoothbox.
      Thanks
      Ken

    • Ken Shaw

      last posting was addressed to Mads

    • Mads Petersen

      I have 2 questions.

      1)
      I would like to auto display the titel of the pictures underneath the thumbs (imagename.jpg)
      (Like a picture in a folder on my HD)
      Any hints on how to do this?

      2)
      When clicking the thumbs i would like the big picture to be displayed Fullscreen.
      Anyone knows if this would be possible some how? I tried to “ask” smartbox through google.. But no luck..

      Any help ore hints will make me happy ;)
      Have a nice weekend.

      Cheers,
      Mads

  59. David Ryder

    I don’t think PHPThumb is overkill. The thumbnails in this script look jagged. The only thing I did was remove the thumbnail generation script and replace the HTML echo statement with this:

    echo '';

  60. Jake

    Hi,

    I would really like to use this script however I would like the images to be squared. ie. the same size.

    Is this possible at all?

    Thanks,

    Jake

    • David Ryder

      You can use the PHP function imagecopyresized to resize images as they are being processed.

  61. Greg

    Nice work again David, thanks for sharing. On some browsers (Safari for example) horizontal scrollbars appear when the thumbnail is clicked… any idea how to kill these? (It doesn’t seem to be a small-screen problem).

    Also, is it easy/possible to create a second gallery on the same page?

    Thanks!

  62. Bert

    Hi,
    Thanks for the code David.
    I’m trying to edit it so that the thumbs are displayed in one long row.
    I also want the page to expand to the right to accommodate the long row of thumbnails.
    No matter what I try, the thumbs always start a new row when they reach the edge of the browser.
    Any ideas anyone?

  63. MOMOC

    Thanks for this script, I really need this kind of script because I’m a freelance photographer.

    From the comment above..some of them like the thumbnaild to be crop..not resized..like this http://scriptandstyle.com/AutoGeneratingGallery/ i wonder how they make the thumbnail crop. This sample comes from the same script with some adjustment.

    Anybody know how to make thumbnail like this.

    Thanks guys,
    apprechiate it

  64. CCM

    Form and function. Love it.

    For the record, and I’m sure almost everyone knows this, but you can’t change filenames and expect this thing to work. For non-programming designers out there, don’t go changing mootools-1.2.4.js to anything shorthand. That’s 4 hours of my life I’ll never see again.

    David, I notice the lightbox appears to “swoosh” in from the bottom left … anyway of just making this a simple fade-in fade-out? If functionality is already there, how would you tell a designer non-programmer type how to change this?

    Great tool and I plan on using it whenever possible. Good work and thank you! BTW … GO BADGERS! Buckeye killers this year.

  65. heymelby

    i am so pissed at this thing, no matter how much i change $thumbs_width, the thumbs remain at 200 pixels! what is causing this?

    help!

    • Bahb

      The thumb that is being showed, is it a .jpg?

  66. Luke Scammell

    Thanks for this excellent script and the clear example, it was just what I needed.

    I agree with various people about the nasty jagged thumbnails so I just replaced the thumbnail generation with PHPThumb (https://github.com/masterexploder/PHPThumb) and now I have nicely resized, cropped thumbnails :)

    Thanks again!

    • Morley Santo

      Would you mind showing how you adapted this to this script?

      Thanks

  67. Ian

    I just can’t get this to work, my file paths all seem to be correct, i guess i am just a moron but i can’t get this to work, i just keep getting there are no files in this gallery, but i can’t see where i am going wrong, can someone give me “the idiots guide” to doing this, i feel it would be so much much better than any other gallery i could use and so much easier once it’s up and running

  68. lisak

    Is there some place I where I can download all files in one package?

  69. Aron Aguiar

    Thanks for the tutorial!! and for some tips by everyone here.. :)
    I’ve got everything to work except for the Smoothbox.
    am I doing something wrong? I don’t want to say what I’ve done because I’ve done exactly like the tutorial says..
    am I missing something? a file? something?
    thanks!

  70. kb

    When I try to use this script I get an error message

    Fatal error: Out of memory (allocated 11272192) (tried to allocate 6400 bytes) in /home/maitland/public_html/gallery/upload.php on line 101

    On line 101 is $source_handle = $function_to_read($images_dir . '/' . $filename);

  71. Matt

    How do i go about sorting by the latest added?

  72. Axess

    Hi !

    Great plugin !

    It’s possible for multiple folder ?

  73. Chuck

    Cant seem to make it work.
    I keep getting “There are no images in this gallery.”

    Ive been frying my brains for over 2 hours…
    Followed Nobody’s walkthrough, changed folders thinking maybe this is a relative/absolute path mistake and still nothing.

    Could someone please make a package of this?
    Pretty please with sugar on top?

  74. Walkoflife

    Hi David,

    a very nice solution. I get it to work when the images are stored in the same folder as the php file that is executed. I am about to include it into an Magento installation and my core images are separated from the file that runs the script. Im passing $this->getSkinUrl(‘images/gallery/collection/’); that holds “http://localhost/magento/skin/frontend/mytheme/default/images/gallery/collection/ ” to the variable $images_dir. The result, “There are no images in this gallery.” Can you help me out here? Give me some hints? I would really appreciate it!

  75. Walkoflife

    This is really nice! But how do I get it to work when my images are separated from the script. I am trying to implement it with my Magento installation. I am passing $this->getSkinUrl(‘images/gallery/collection/’); that holds “http://localhost/magento/skin/frontend/mytheme/default/images/gallery/collection/” to $images_dir. That gives me the result “There are no images in this gallery.” Can you help me out here? I would really appreciate it!

  76. Mihir Chhatre

    Could someone please illustrate how i can make those thumbnails square using this?

    http://return-true.com/2009/02/making-cropping-thumbnails-square-using-php-gd/

    I think this was mentioned in one of the earlier posts!

    Thanks!

    Mihir.

  77. Elliot

    Has anyone had an issue of the images not appearing in order?

  78. WeB DiZajN

    TY for this very good info. :)

  79. Travonta

    I’m trying to use this script and I have the gallery working properly, however it keeps replicating the entire gallery anytime the page is refreshed. What can I do to prevent this?

  80. Vikas

    i got this error

    Parse error: syntax error, unexpected ‘;’ in /home/media125/public_html/ingamepic.co.cc/new.php on line 37

  81. Falcon

    What happened to the original Chris Coyier tutorial? The link no longer works :( I’d much rather use that one, unless of course the thumbnails can be automatically generated to be the same size without warping the image.

  82. Falcon

    No wait, never mind! I used this one. Only reason I was attracted to the old auto gallery was because of the beautiful square cropped thumbnails. But I’m loving the auto thumbnails I must say.

    Just want to chime in with the rest of them on how to add the square cropping code mentioned above.

  83. Peter

    Hi,

    Great tutorial, thank you.

    Have a question though. How hard would it be to modify it to handle subdirectories?

    Tried to combine it with another solution but failed unfortunately.

    Was also thinking about creating the thumbnails in a similar way using the same dir structure as the images.

    Do you have any suggestions? All ideas are appriciated.

    Thank you.

  84. Kelly

    Hi there :)

    Managed to work out your tutorial and am pretty pleased since I’m very new to PHP… But I was wondering, I would very much like all my thumbnails to be the same width and height, even though some are portrait and some are landscape. How would I edit your code to change the image height to be fixed to take part of the image?

    Hope I am making sense! :) Thanks for your help :)


Be Heard!

Share your thoughts without being a jerk! And wrap your code in <code> tags, f00!

Name*:
Email*:
Website: