Runtime Revolution
 
Articles Other News

Image is Everything


by Tim Shields


I have an old laptop at home, which over the years has taken quite a beating and has everything (including the kitchen sink) installed on it. As a result, it now takes the best part of 30 minutes just to boot up. I don't want to re-format the drive and re-install windows as there is a bunch of files and applications that I may need in the future and as I only really use it now for web-browsing and looking at photo's, I decided to use Puppy Linux – a small, live CD linux distro – to breath new life into the machine.

However, there is no simple image browser installed in puppy – you know the kind of thing – file tree at one side, thumbnails the other and a big image view in the middle. Now here is a good 20 minute project for Revolution I thought, so I set about writing such an application.

What I wanted to create was a simple way to browse my photo collection – something that supported thumbnails (with a thumbnail cache for speed), folder navigation and was so simple to use my computer illiterate girlfriend could use it.

And this is what I came up with.

You can grab a copy of this application by typing

go stack URL "http://www.runrev.com/newsletter/november/issue36/imagebrowser.rev"

into the revolution message box.

The code is very heavily commented, so that you can take it apart for yourself and see how each part works. Just open it in Revolution, bring up the Application Browser, and study the scripts for each part of the Image Browser.

Rather than dissecting this application bit by bit I want to draw your attention to some of the concepts that are used.

  1. The use of templateImage.
  2. The creation of self-contained re-useable object groups
  3. Creating a thumbnail using import snapshot
  4. Using a "send <message>" loop to allow responsiveness throughout the application.

1. The use of templateImage

Sometimes it is very useful to set up a set of default values that you wish any newly created object to inherit – for example to set some default width or heights. Revolution allows you to do this by the use of the template objects.

Setting up the defaults on the templateImage (or any of the template Revolution objects) allows you to specify default properties and behaviours for any newly created images.

set the width of the templateImage to 100
set the height of the templateImage to 100
set the border of the templateImage to true
set the threeD of the templateImage to false
set the borderwidth of the templateImage to 1
set the locklocation of the templateImage to true

For more information about using template objects in Revolution, see the Dictionary entries for templateImage, templateCard, templateGroup, and a number of other objects that have this property. You will find the Dictionary under the Help/Documentation menu inside Revolution.

2. Creation of self-contained object groups

One of the most powerful aspects of Revolution is the way that you can code self contained objects or groups of objects. In this application the thumbnail group on the right hand side is a good example.

The group itself contains all the scripting you need to manage thumbnails and provides a simple interface of two calls:

  1. resetImages
    Clears all the images from the thumbnails view
  2. reloadThumbnails
    Generates thumbnail images for any JPG, GIF or PNG image files it finds in the current folder, using any cached thumbnails if available.

Designing an application in this manner means you can copy the thumbnail group onto a fresh stack and simply call those two methods and the group will manage everything else for you. You will also need to copy the "status" group which provides the status bar etc. To look at the entire script for this group, click on the group called "thumbnailView" in the Application Browser, and bring up the script by clicking on "Script" in the toolbar.

3. Creating a thumbnail using Import Snapshot

As you know, it is very easy to load images and resize them – and you would be forgiven for thinking that this is all that is required to create a thumbnail view of an image file. However, when you resize an image in Revolution you still retain all the data that was in the original file. Although this will work, you will very quickly run out of memory if you try and load in thumbnails of a folder containing several hundred large images.

What we actually want to achieve is to create a thumbnail that just contains that actual data of the smaller, resized image. This file can then be written out to disk to create a thumbnail cache.

The easiest way to achieve this is to use the import snapshot command. Below you will find the main steps to achieve this.

  1. Create the new empty thumbnail image
    create image in group "thumbnailView"
  2. Create a temporary blank image of the correct size for the thumbnail
    create invisible image "Foo"
  3. Set the filename of the temporary image to the image on disk
    set the filename of image "Foo" to tFile
  4. The image will be automatically resized to fit the new temporary image
  5. Create a snapshot of the temporary (resized) image
    import snapshot from rect (the rect of image "Foo") of image "Foo"
  6. Put the data of the snapshot into our thumbnail
    set the text of image id tID to the text of the last image
  7. Clean up after ourselves
    delete the last image
    delete image "Foo"
  8. Optionally, save the thumbnail image to disk cache

You can see exactly how I used this in the Image Browser, the script is at the bottom of the "thumbnailView" group script, in the function called "processImage". Again, you can look up import snapshot in the Dictionary for more information on how to use this versatile command.

4. Send message loops

When it came to processing the list of image files into thumbnails I did it first using a simple "repeat with line tFile in tFileList" loop. However, doing things this way means that the application is locked up and unresponsive until all images have been processed – there is no-way to change folder, view an image or even cancel the listing until all files have been processed.

Luckily, Revolution provides a simple way to loop through the list while still allowing responsiveness to other events – the "Send" message loop.

Firstly, the reloadThumbnails function starts the processing loop up by sending itself the "processImage" message right away – tFiles contains the list of image files.

send "processImage tFiles" to me in 0 millisecs

The "processImage" handler processes a single image file into a thumbnail (as outlined in the section above). The last thing the "processImage" handler does is call itself using the "send" command but with a small delay. This delay allows Revolution to process any other events that may have occurred – mouse clicks on the folder tree for example.

if pImageList is not empty then
send "processImage pImageList" to me in 25 millisecs
end if

I hope you find this information useful. My girlfriend is now happily browsing photos of me as a baby so I guess the application is fulfilling its destiny, but I really should have checked the contents of that laptop before installing...

 
©2005 Runtime Revolution Ltd, 15-19 York Place, Edinburgh, Scotland, UK, EH1 3EB.
Questions? Email info@runrev.com for answers.