Sunday, April 14, 2013

Creating an Image Gallery in HTML5



Disclaimer:


  1. This example works easily on any Linux distribution. OS X users need to install ImageMagick or GraphicsMagick via MacPorts or Homebrew. Windows users need to install Cygwin/X.
  2. People, who believe that the "width" and "height" attributes of the HTML tag are sufficient for scaling images should immediately shut down their computer, and never, ever attempt to design a web page agin.


This article describes steps on how to create an image gallery for a web site. We are going to use HTML5 elements, which are now supported by a large number of browsers, including WebKit, Safari, Google Chrome, Firefox, and Opera. Internet Explorer 9 is supposed to catch up. Our objective is to use the most recent advanced in browser development to create elegant and efficient applications. For the real world, however, additional steps are needed to guaranty users of older browsers a satisfying experience. View live demo at http://petermolnar.us/demos/ImageGallery/

Our goal is to quickly create an image gallery from a large set of photographs. We want to be able to add pictures in the future, and even create additional galleries. We assume that new photographs are added in chunks, and only occasionally: daily, once a week, etc. Therefore, producing the gallery on the fly is not required.

The proposed method does not require server side scripting. The gallery will be created off-line, and the resulting files can be transferred to the server. However, we make use of the powerful Command Line Interface (CLI) and shell scripting.
The examples run on any POSIX based operating system, including Mac OS X and Linux. Shell Scripting or batch scripting is also supported by Microsoft Windows, though, this technique is less known by Windows users.

Image Manipulation

Image manipulation software like Adobe's Photoshop and Gimp are powerful applications when manipulating individual images. However, running the manipulation on hundreds of images is not that easy. Instead, we are going to make use of the command line tool ImageMagick http://www.imagemagick.org/.

The package comes with a number of commands whereby convert is pretty much all we need to deal with. The page http://www.imagemagick.org/Usage/thumbnails/ shows how to create a number of different types of thumbnail images. For this example we use the quirky Polaroid feature.
Most photographers take pictures in very high resolution; too large for the web. Usually, images on web-sites should fit within a box 600 to 800 pixels wide and high. The convertcommand offers an easy re-size function that respects the aspect ratio of the image.

$ convert OriginalImage.jpg -resize 600x600 SmallerImage.jpg

The command works for images in landscape and portrait mode. The command also converts images from one format to another based on the given file extension. The ImageMagick package also features a command identify the get information about size, resolution and color model from a given picture. Since identify is not included in the Mac OS X implementation we have to resort to

$ convert Image.jpg -identify null:

Processing Images

Save the following code into process_images.sh


#!/bin/bash
#
for i in raw/*.JPG; do
   n=`basename $i .JPG`;
   echo -n "processing $n ..."
   convert $i -resize 600x600 images/$n.jpg
   convert $i -resize 150x150 -bordercolor '#EEEEEE' -background '#333333' +polaroid thumbs/$n.png
   echo " done."
done

Producing re-sized images and thumbnails is just one part of the job. If we consider that we may have to deal with hundreds of images we also need a way to automatically create HTML code. The example given here produces a complete page. However, more comprehensive projects would use external CSS and JS files.

#!/bin/bash

echo '
 <!DOCTYPE HTML>
 <html>
 <head>

 <style>
 div.thumbnail { width: 200px; height: 200px; vertical-align:middle; text-align: center; display: inline; }
 div.thumbnail img:hover { position: relative; top:-5px; }
 </style>
 </head>
 <body>
 <div id="thumbs">
'

for i in raw/*.JPG; do
    n=`basename $i .JPG`;
    echo "<div class=\"thumbnail\" id=\"thumb$n\" >";
    echo "<img src=\"thumbs/$n.png\" onclick=\"showImage('$n')\" />"
    echo "</div>"
done

echo '
 </div><!-- #thumbs -->
 </body>
 </html>
'

The final output looks something like this:

<!DOCTYPE HTML>
<html>
<head>

<style>
/* #spacer { background: white; height: 500px; } */
#thumbs { background: white; text-align: center;}
div.thumbnail { vertical-align:middle; text-align: center; display: inline; }


div.thumbnail img:hover {
   position: relative; top:-5px; left: 5px;
   -webkit-transform: rotate(10deg);
   -moz-transform: rotate(10deg);
   -o-transform: rotate(10deg);
}

/*#imagedisplay { width: 100%; position: fixed; top: 30px; left: 0px; text-align: center;  } */
#imagedisplay {position: fixed; top: 30px; left: 50%; width: 0px; }

.invisible { display: none;} 
#picture {
    position: relative; left: -320px; 
    border: #EEEEEE solid 20px;
    -webkit-box-shadow: 5px 5px 15px #000000; /* Safari and Chrome */
    box-shadow: 5px 5px 15px #000000;
}
</style>

<script>
function showImage(name) {
   pic = document.getElementById("picture")
   pic.src="images/"+name+".jpg"
   pic.className="visibile"
}
</script>

</head>
<body>

<div id ="imagedisplay">
  <img id="picture" class="invisible" onclick="this.className='invisible'" />
</div>
<div id="spacer"></div>
<div id="thumbs">

<div class="thumbnail" id="thumbCIMG0494" >
<img src="thumbs/CIMG0494.png" onclick="showImage('CIMG0494')" />
</div>

All the other images ...

<div class="thumbnail" id="thumbCIMG0740" >
<img src="thumbs/CIMG0740.png" onclick="showImage('CIMG0740')" />
</div>

</div><!-- #thumbs -->
</body>
</html>