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 LiveCode" I thought, so I set about writing such an application.
You can download the lesson for this stack here: https://tinyurl.com/ybj3mhfw
The basic 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 simple to use.
And this is what I came up with.
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 Rev, 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.
* The use of templateImage.
* The creation of self-contained re-useable object groups
* Creating a thumbnail using import snapshot
* Using a "send " loop to allow responsiveness throughout the application.
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. LiveCode allows you to do this by the use of the template objects.
Setting up the defaults on the templateImage (or any of the template Rev 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 showBorder 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
Creation of self-contained object groups
One of the most powerful aspects of Rev 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:
resetImages - Clears all the images from the thumbnails view
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.
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 Rev 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.
Send message loops
When it came to processing the list of image files into thumbnails I did it first using a simple loop
repeat with line tFile in tFileList
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, Rev 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 Rev 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