QAlbum: Scripts for Digital Pictures

The idea of these scripts is that each folder (directory of images) contains a descriptior file named index.xml, which lists the images, along with captions or other descritive information. This index.xml can be created and managed using various tools/scripts, or edited manually with a text editor. Then running qalbum generates all the HTML pages, creating scaled images as needed. The resulting web pages can be uploaded to a web server, or browsed as-is from the file system. You can go back and edit the index.xml, and then re-run qalbum to get an updated web folder.

Here is an example page that illustrates many qalbum features, and here is the picture group file describing it.


There are a number of tools which do similar things. This one has some nice little extras:

File naming convention

A suggested naming convention: Each .jpg file should follow this naming convention: prefixNnX.jpg, where prefix is name common to a group of files, and Nn is a serial number. (Hence prefix should not end in a digit.) The X is an optional code letter, for scaled/rotated images that are normlly generated automatically: Where r means the picture is right-side-up but rotated relative to the camera original; p is a page-size image (scaled and perhaps cropped and rotated so it is suitable for viewing in a web page by itself); and t means a thumbnail image (scaled to show multiple images per page).

Suggested procedure

If you have a group of pictures you want to web-ify, this section gives suggested instructions for what to do.

If needed, create a lib directory

The lib directory contains files that are shared between albums - currently two JavaScript files and help.html. The directory can be anywhere, if you explicitly specify the --libdir=directory when running However, if you use ../lib, ../../lib, or ../../lib (relative to the album you're working on) then the scripts will find it automatically. So create a directory named lib next to your top-level album. When you run qalbum later, it will copy the necessary files over.

Generate initial overview files

I assume the qalbum script is in your path. (Alternatively, you can type the full path instead iof just qalbum.)

Start by putting the .jpg files in the desired directory. Then cd to that directory.

Run the qalbum script as follows. If you follow the naming convention given below, you can do:

qalbum new "Title" image1.jpg ... imageN.jpg

Here "Title" is the name you want on the title page of your overview page, and image1.jpg ... imageN.jpg are the image you want to display.

You can leave out the image1.jpg ... imageN.jpg list. In that case qalbum will make a list from all the .jpg files in the directory which have the form prefixNN.jpg (i.e. without the X code letter). The images will be sorted by the NN sequence numbers - not alphabethically.

Either way, this creates an initial index.xml. It also creates an initial set of web pages. If the current directory is /home/me/vacation, then you can view the web pages and images by pointing your browser at file:/home/me/vacation/index.html.

Unrotating rotated picture

Many modern cameras can detect their orientation (i.e. if the camera is rotated), and write that into the saved file. The qalbum script can detect this (at least for some cameras), and automatically takes care of the rotation. If you have such a camera, you can skip this section.

Suppose when viewing index.html, a picture is rotated 90 degrees counter-clockwise (to the left). In that case, edit index.xml to add in the corresponding <picture> section:

<original rotated="left"/>

If the picture is rotated 90 degrees clockwise (to the right), instead add the following:

<original rotated="right"/>

Then run:


This creates rotated copies of the files you specified as <orginal rotated="xxx">, and also edits index.xml for you. If the original file was named xxxNN.jpg, the rotated file will be named xxxNNr.jpg.

Check index.html with a browser to see if you got it right. If you didn't, re-edit index.xml. For any picture that was rotated the wrong way, delete the rotated file:

rm xxxNNr.jpg

Re-run qalbum. Check again; continue until all the pictures are right way up.

Format of the picture-group file

A picture-group file is an xml file, which looks rather like an html file, but with different tags (element names). Also the syntax is more strict: For example, for every start tag (such as <text>) you have to include the end tag (e.g. </text>), and they have to be properly nested. Also, attribute values (such as in width="1280") have to be quoted (with single or double quotes).

The <group> element:
Each picture-group file contains a single <group> element. Each <group> must contain <title> element, followed by any number of <date>, <picture>, and <text> elements.

The <title> element:
This must appear in <group> element (usually at the start), and contains the title of the folder. It should be a short phrase describing the pictures in the group. It is used for the HTML <title> of the overview page, and can contain whatever HTML markup is legal for that.

The <picture> element:
Each <picture> element describes one image. It must have an id attribute, which is used to name the web page generated for that picture. The <picture> must contain an <image> element, and may optionally contain <caption>, <text> (zero or more), <date>, and <original> elements. (Old index.xml may also contain <full-image> and <small-image> elements.)

The <image> element:
This contains the name of the actual jpg image file. This is normally the original, un-rotated, un-scaled image downloaded from the camera. (In old index.xml files, this is used for the scaled medium-sized image, and <full-image> is the large un-scaled file.)

The <date> element:
Each <picture> may also have a <date> element specifying when the picture was taken. The format is not free-form; I suggest (and the qalbum script generates) YYYY/MM/DD. (Unfortunately, ISO format YYYY-MM-DD is awkward for ranges.) The <date> can appear in a <picture>, or at <group> level; in the latter case it applies to all following <picture> until overridden.

The <caption> element:
Each <picture> may in addition have a short <caption>. This is used as a short description of the picture in the overview page, and it is used as the page title in the picture page. It can contain HTML markup.

The <text> element:
This can appear either in a <group> or in a <picture>. In both cases, it can contain aribitrary HTML markup, and is formatted as a paragraph. (Multiple <text> elements translate to multiple HTML paragraphs.) Any <text> elements at <group> level (i.e. not in a <picture>) are displayed on the overview page, the slider, and the next following picture page. Any <text> elements inside a <picture> are only displayed on that picture's page, not the overview page.

The <original> element:
This is used to mark an image that was rotated. It has n attribute rotated, which value is either "left" (if the original camara image is rotated 90 degrees left) or "right" (the original was rotated right).

The <outtake> element:
This is used to name alternative but presumably inferior images. It has the form:
<outtake img="filenameNN.jpg"/>
<outtake img="filenameNN.jpg">descriptive-text</outtake>
The elements are ignored, except in the information page of the enclosing <picture>, which contains links to the outtake images. This allows the interested viewer to look at alternate images, without cluttering up the normal view. Note that you would remove <picture> elements for outtake pictures, and instead place <outtake> elements in the selected (non-outtake) <picture> elements.

Obsolete entries, which you might see in old index.xml files:

The <full-image> element:
This used to contain the name of the large unscaled image file.

The <small-image> element:
This used to contain the name of the thumbnail-sized scaled image file.

The <row> element:
This was seldom used, but could be used to ensure that a group of <picture> are all displayed on the same row in the overview page. If you leave out <row> elements, the pictures will be displayed as many as will fit on a line. (It used to be 3 on a line, except that if there were 4 pictures they would be displayed as 2+2

The <select> element:
Select pictures based on a file-name pattern. The attribute path=path names the pattern. Symbolic links will be created for the files that match path. The pattern names a file path with certain special characters: The character * matches any character (except /). The pattern {num1..num2} matches any integer in the range from num1 to num2 inclusive. These special characters are not allowed in the directory (if any) of the path. The attribute quality=min-quality is used to select only the pictures that have the mininum quality rating (or that are unrated). The attribute as=path can be used to specify the name to be used for links.

The <select> element may have <picture> child elements. Then any information in the <picture> element will override or add to that extracted from the file, such as a <caption>.

Installing: Files to download and dependencies

These scripts have been run using the Qexo (Kawa XQuery) XML processor. There is an (old) article that explains how it works.



Get qalbum-1.2.tgz or a later version from Note that not all versions of qalbum-XXX.tgz are going to compabitble for all versions of Kawa, but the latest versions should work.


Extract qalbum.tgz into a suitable directory.

In that directory create a kawa.jar link:

cd qalbum && ln -s /my/path/to/kawa-1.9.1.jar kawa.jar

The following step is optional, unless there is some version inconsistency between qalbum-version.jar and Kawa. It does require JDK, rather than just JRE, and a Unix-like environment (like GNU/Linux, Mac OS X, or Cygwin)::

make clean && make

You might want to create a symlink from some directory on your $PATH to the qalbum/qalbum script.

That should be it. The qalbum script is smart enough to chase symlinks and find the needed helper files. It assumes either of the environment variables JAVA or JAVA_HOME has been set, or java is in your $PATH.

Home page

The qalbum home page.

Author and license stuff

These scripts were written by Per Bothner <Per Bothner>.

You are free to use these for your own images (personal or business). I of course make NO WARRANTY; if they should happen to destroy your critical files, I'm sorry, but you should have been more careful.

If you use qalbum for you pictures, I would appreciate hearing about it.

Please do not redistribute the scripts in a product or as part of some other software distribution without permission. I expect you to customise the scripts for your own use; if you make significant enhancements, I would appreciate hearing about it.

Per Bothner
Last modified: Sat Aug 25 13:19:47 PDT 2007