Building an Image Index

If you’ve ever visited an image library on the Internet, you’ve probably enjoyed (even taken for granted) the way a collection of small thumbnail images acts as links for full-sized counterparts. Many artists, when presenting a portfolio online, adopt this effective approach to displaying their work. With the rise of digital cameras and scanners, more and more people are finding themselves pulling directories full of images onto the Web in a format that makes for easy browsing. In the next section, we build a Python script that takes a full directory of images and thumbnail images and creates a master HTML page with the thumbnails acting as links to the full-size image. The saxthumbs.py program expects you to have a pre-existing directory of images and thumbnails, and operates on the output of the index.py script we created earlier.

In order for the saxthumbs.py SAX handler to correctly process a thumbnail directory, the images need to follow a naming convention (easily changeable by editing the code). Currently, the saxthumbs.py handler expects to find file elements within the XML document that have a corresponding <imagename>.jpg file that is the entire image, and a t-<imagename>.jpg file that is a thumbnail-size image.

When using index.py to create a list of your image files, point it to a directory that has image files named accordingly:

$> ls -l *newimage*
-rw-rw-r--   1 shm00    shm00       98197 Jan 18 11:08 newimage.jpg
-rw-rw-r--   1 shm00    shm00        5272 Jan 18 11:42 t-newimage.jpg

In this manner, every file that ends in .jpg and has a corresponding t-<imagename>.jpg file (note the size differences) is assimilated into the thumbnail index.

Creating Thumbnail Images

There is an easy way to set up your image files on Unix systems, using the convert command. This command is part of the ImageMagick package, and is installed by default by most modern Linux distributions. For other Unix systems, the package is available at http://www.imagemagick.org/.

$> convert image.jpg -geometry 192x128 t-image.jpg

This will take image.jpg, no matter how large it is, and make a 192x128 size thumbnail in JPEG format. Of course, if the image is a Windows bitmap image (with the .bmp extension), you can do a two-step operation to get JPEG files:

$> convert image.bmp image.jpg
$> convert image.jpg -geometry 192x128 t-image.jpg

Now that you understand how convert works, you can use a simple shell loop to produce small thumbnail images for every .jpg in your image directory:

$> for each in *jpg
> do
> convert $each -geometry 192x128 t-$each
> echo $each
> done

You should end up with the following:

-rwxrwxr-x   1 shm00    shm00       97003 Jan 16 22:40 mvc-001s.jpg
-rwxrwxr-x   1 shm00    shm00       93373 Jan 16 22:40 mvc-002s.jpg
-rwxrwxr-x   1 shm00    shm00       86619 Jan 16 22:40 mvc-003s.jpg
-rwxrwxr-x   1 shm00    shm00       94894 Jan 16 22:40 mvc-004s.jpg
-rwxrwxr-x   1 shm00    shm00       76210 Jan 16 22:40 mvc-005s.jpg
-rwxrwxr-x   1 shm00    shm00       73704 Jan 16 22:40 mvc-006s.jpg
-rwxrwxr-x   1 shm00    shm00       80292 Jan 16 22:40 mvc-007s.jpg
-rw-rw-r--   1 shm00    shm00        4434 Jan 21 11:46 t-mvc-001s.jpg
-rw-rw-r--   1 shm00    shm00        4181 Jan 21 11:46 t-mvc-002s.jpg
-rw-rw-r--   1 shm00    shm00        3604 Jan 21 11:46 t-mvc-003s.jpg
-rw-rw-r--   1 shm00    shm00        4634 Jan 21 11:46 t-mvc-004s.jpg
-rw-rw-r--   1 shm00    shm00        3339 Jan 21 11:46 t-mvc-005s.jpg
-rw-rw-r--   1 shm00    shm00        2777 Jan 21 11:46 t-mvc-006s.jpg
-rw-rw-r--   1 shm00    shm00        2996 Jan 21 11:46 t-mvc-007s.jpg

This listing represents the convert program applied against mvc-00*.jpg files taken with a digital camera. The saxthumbs.py script produces markup to display both the thumbnails and each individual image.

If you run index.py against this directory, you create an XML file that we are able to use a little later in the chapter when we go over the saxthumbs.py process:

$> ./index.py /home/shm00/images/ img.xml

The new file, img.xml, contains file elements that detail your image files in a format appropriate for the script to manipulate.

Creating thumbnails on Windows

If you don’t have access to Unix (or a scriptable image processor for your operating system), you can create your own image directory on Windows. Just be sure to resize originals and prefix the thumbnails with t-, and make sure that all of the images to be displayed on the Web are in JPEG format (ending with .jpg). For example, if you open the My Pictures directory in Photoshop, you can take each image, resize it to 192x128, and save it as a t- version of its original self.

To come back around to our example, once you prepare the directory, you can point index.py at it and generate an XML index file for the images.

Implementing the SAXThumbs Handler

The SAXThumbs handler creates an anchor for each thumbnail in the HTML output file, and creates a standalone HTML document to display the full size image. Then, SAXThumbs leaves you with an HTML page showing all of your thumbnails, as well as an HTML page for each full size image.

The SAXThumbs handler is implemented as a class inheriting from ContentHandler. The name of the output file, which should contain a preview of all of the thumbnails, is supplied as a command-line parameter and passed to the constructor:

def __init__(self, thumbsFilename):
  self.filename = thumbsFilename

def startDocument(self):
  self.fd = open(self.filename, "w")
  self.fd.write("<html><body>
")

def endDocument(self):
  self.fd.write("</body></html>
")
  self.fd.close(  )

When the end of the XML document is reached, it’s assumed that there are no more image files to process, and the thumbnails document is closed.

The rest of the work is done in the startElement method. First, the image name is copied without its path information:

def startElement(self, name, attrs):
  if name == "file":
    filename = attrs.get("name", "")

    # pull out just the filename
    dir, localname = os.path.split(filename)
    localname, ext = os.path.splitext(localname)

Then, the file is examined to determine whether it’s a thumbnail or a full image. Thumbnails have HTML anchors around them, which are then added to the thumbnails output file:

    if localname.startswith("t-") and ext == ".jpg":
      # create anchor tag in thumbs.html
      fullImgLink = localname[2:] + ".html"
      self.fd.write('<br><a href="%s"><img src="%s%s"></a>
'
                        % (fullImgLink, localname, ext))

If the image is not a thumbnail, but a full image, then a separate HTML file is created that displays the image:

    fullImageFile = os.path.join(dir, localname) + ".html"
    print "Will create:", fullImageFile

    fullImageHTML = ('<html><body><img src="%s%s"></body></html>
'
                     % (localname, ext))

    lfd = open(fullImageFile, "w")
    lfd.write(fullImageHTML)
    lfd.close(  )

The full-image HTML file is created in the same directory that holds the image. The thumbnails file is created in the same directory from which you’re running thumbmaker.py. Example 3-6 shows saxthumbs.py.

Example 3-6. saxthumbs.py
from xml.sax import ContentHandler

class SAXThumbs(ContentHandler):
  """
  This is the SAX handler that generates a full-
  image display (an .html page) for each image file
  contained in the XML file.

  It also adds an anchor on the thumbs page showing
  the thumbnail, and linking to the big image page
  that was created first.
  """
  def __init__(self, thumbsFilename):
    self.filename = thumbsFilename

  def startDocument(self):
    self.fd = open(self.filename, "w")
    self.fd.write("<html><body>
")

  def endDocument(self):
    self.fd.write("</body></html>
")
    self.fd.close(  )

  def startElement(self, name, attrs):
    if name == "file":
      filename = attrs.get("name", "")
      # slice out just the filename
      dir, localname = os.path.split(filename)
      localname, ext = os.path.splitext(localname)

      if localname.startswith("t-") and ext == ".jpg":
        # create anchor tag in thumbs.html
        fullImgLink = localname[2:] + ".html"
        self.fd.write('<br><a href="%s"><img src="%s%s"></a>
'
                      % (fullImgLink, localname, ext))

        fullImageFile = os.path.join(dir, localname) + ".html"
        print "Will create:", fullImageFile

        fullImageHTML = ('<html><body><img src="%s%s"></body><html>
'
                        % (localname, ext))
        lfd = open(fullImageFile, "w")
        lfd.write(fullImageHTML)
        lfd.close(  )

The thumbmaker.py file is a script that loads the XML from standard input, and registers the SAXThumbs class as the chosen handler to use with the SAX parser. Example 3-7 shows thumbmaker.py in its entirety.

Example 3-7. thumbmaker.py
#!/usr/bin/env python
# thumbmaker.py

import sys

from xml.sax   import make_parser
from saxthumbs import SAXThumbs

# Main

ch = SAXThumbs(sys.argv[1])
parser = make_parser(  )

parser.setContentHandler(ch)
parser.parse(sys.stdin)

It is interesting to note the similarity to the first script that we wrote in Example 3-2.

To run thumbmaker.py, you first need to make sure you have created the right type of directory containing image files and that you’ve run index.py across the directory to generate an XML file containing the list of files. Once you have these items, you can pick a name for the index file (such as mythumbs.html) and pass it to the script:

$> python thumbmaker.py mythumbs.html < img.xml

In this case, mythumbs.html is the output file, and the XML source is received from the file img.xml.

Viewing Your Thumbnails

After executing thumbmaker.py, you are left with a thumbnails file that is sitting in your current working directory. You should move this file to the directory that is holding your images:

$> mv mythumbs.html /home/shm00/tw/zero/images/
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.4.191