Automatically Generate a Photo Gallery from a Directory of Images: Updated
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
Be Heard!
Share your thoughts with fellow developers of all skill levels! I want to hear from you!
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().
Another example with Christina Ricci, I’m starting to think you make this tutorials just to post a photo gallery of her… :)
Why don’t you use
scandir()?@Mathias Bynens: My solution is PHP4 compliant, as much as people probably don’t care.
Very cool! Nice automation of PHP.
nice article. this gave me an idea for a theme that I was working on. I am going to use this. Thanks.
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!
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.
@Mathias – I didn’t know this function. Thanks!
@David – Good tutorial, best regards!
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.
detail. I like picture 2 a lot :P nice work!
@William Rouse: And how did you do it? I’m pretty interested in PNG and GIF support too…
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.
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….
@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.
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.
@Matěj Grabovský: Would you demonstrate how to rewrite the function using the methods you suggested and are available in PHP5
Thanks!
WBR
@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…
@SeanJA: (It being PHP4…)
@SeanJA: I suppose — I dont’ think it’s that big of a deal.
@William Rouse: Could you not just use imagecreatefromstring instead?
I just read the docs on imagecreatefromstring. Please show me how to use it.
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?
@Justin: Use PHP’s exif_read_data to read any EXIF comment in the JPG file, and use this as the caption.
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.
Don’t you know glob()? It’s really useful, you could save a lot of lines. :)
@William Rouse: The get_files functions could be rewritten like this: http://gist.github.com/361919
@William Rouse: Sorry, fixed link: http://gist.github.com/361922
@Matěj Grabovský: Thanks for the code.
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!
Thks nice article
can you make a package to download, please.
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!
could see the GD library used to generate small images … winning hard disk space
I say :P
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!
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.
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.
@Vinnie: Posting the same question repeatedly is obviously the way to get help.
@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.
@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
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
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.
Very useful script, thanks! I’m also wondering how to sort the thumbnails; preferably alphabetically. Any suggestions?
@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);
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
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,
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….
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.)
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.
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)
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!
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>
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
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.
Anyone have a way of create multple galleries from this script?
Found an alternative that supports subfolders
http://sye.dk/sfpg/
Thank you – went and got it – looks promising!