Writing Your Own Image Gallery Application with the UNIX Shell

You don't need a fancy photo management application to create a Web-based image gallery.
The Code for the Task

It is best to use /bin/sh as the programming language. Because all the work is already done most elegantly and naturally by command-line utilities, you need only to invoke them with the appropriate switches and generate simple HTML code a la google.com.

The first task is to segregate the images into different directories, depending on the dimensions and orientation of each image. This is easily done with the following block of code:


# script to segregate images based on dimensions

for image in *jpg
dimension=`identify -format "%wx%h" $image`
# we don't want mkdir shouting at us for 
# directories that exist!
mkdir $dimension 2>/dev/null 
mv $image $dimension

Now we have all images of identical dimensions, neatly arranged in separate directories. Let's proceed to generating the thumbnails for each of them. This script generates the thumbnails:


# script to segregate images based on dimensions

# this is where we have all the thumbnails for each of the
# images classified by dimensions above
mkdir thumb
for dir in `ls -F |grep / | grep ^[0-9] `
 mkdir thumb/$dir 2>/dev/null
 cd $dir
 width=`echo $dir | cut -dx -f1`
 height=` echo $dir | cut -dx -f2 | cut -d/ -f1 ` 
 for image in *
   convert -size ${width}x${height} $image  -resize 20% \
 cd ..

With ImageMagick, you have several nice features available for decorating thumbnails, and they look impressive.

1) Thumbnail with thickness and shadow:

$ convert rose.jpg -matte \
    \( +clone -fx DarkSlateGrey -repage +0+1 \) \
    \( +clone -repage +1+2 \) \
    \( +clone -repage +1+3 \) \
    \( +clone -repage +2+4 \) \
    \( +clone -repage +2+5 \) \
    \( +clone -repage +3+6 \) \
  -background none -compose DstOver -mosaic rose-thickness.jpg

2) A raised button effect:

$ convert -raise 8x8 rose.jpg rose-raised.jpg

3) Adding a frame to the thumbnail:

$convert -mattecolor peru -frame 9x9+3+3 rose.jpg rose-frame.jpg

Figure 1. Image with Frame

Next, let's look at some interesting ways to annotate images with ImageMagick:

1) Text on the bottom-left corner with a vertical orientation:

$ convert rose.jpg -font helvetica -fill white \
  -pointsize 20 -gravity southwest -annotate \
  270x270+15+0 'Nice pink rose' rose-text.jpg

Figure 2. Image with Text

2) Text on a frame:

$ montage -geometry +0+0 -background white -fill \
  brown -label 'Nice pink rose' rose.jpg rose-text.jpg

Note that you can give any color to the -background and -fill switches. To find which colors are supported by ImageMagick, type:

$ convert -list color

3) You also can watermark, like this:

$ convert rose.jpg -font helvetica -pointsize 20 -draw \
    "gravity south  \
      fill black text 0,12 'Nice pink rose' \
      fill white text 1,11 'Nice pink rose' " rose-text.jpg

Figure 3. Image with Watermarking

4) Label the image on the top like this:

$ convert rose.jpg -gravity North -background green \
  -splice 0x18 -draw "text 0,0 'Nice \
  pink rose' " rose-top.jpg

You can create a video from the images using mencoder or FFmpeg. But before that, let's first create the horizontal and vertical mirror images of the snaps. It will be interesting to combine the images with the mirrors while playing the video:

$convert rose.jpg -flip rose-flip.jpg
$convert rose.jpg -flop rose-flop.jpg

These two commands create the vertical and horizontal mirror images, respectively.

You can combine the mirrors with the original with the append switch to convert:

$convert rose.jpg rose-flip.jpg -append rose-vertical.jpg

Instead of -append, if you specify +append, it creates the images side by side, which is what we want to do with horizontal mirror images:

$convert rose.jpg rose-flop.jpg +append rose-horiz.jpg

You might consider using the -resize option or -scale option to convert all images to identical dimensions:

$ mencoder "mf://*.jp" -mf fps=0.5:type=jpg -o \
  image-video.avi -ovc lavc -lavcopts vcodec=mjpeg

This creates an image video with all the images displaying one after another at an interval of one image every two seconds (fps=0.5). But, bear in mind that all the images need to have identical dimensions, or this will not work.

Now, you can combine this with a nice audio file to create a video that is playable on a DVD:

$ lav2yuv +n image-video.avi | mpeg2enc -f 8 -o image-video.m2v
$ mplex -f 8 audio.ac3 image-video.m2v -o final-video.mpg

Now, simply copy the final-video.mpg into your DVD and you are done.

You can generate the black-and-white equivalents of a color image using this command:

$ xloadimage rose.jpg -dump jpeg,grayscale rose-bw.jpg