I wrote up a quick and dirty slide show application in ColdFusion 8 and thought I'd share the code. While it isn't very pretty (I have a second version to show you tomorrow), it gets the job done. First take a look at the demo, and then I'll describe the code:
The demo makes use of two ColdFusion 8 features - image support and and the cflayout tag. Let me talk first about how the images are handled. I begin by getting a list of all the files in a folder:
<!--- get my images --->
<cfdirectory action="list" directory="#folder#" name="images" type="file">
Note the new type attribute. This lets you filter a directory listing to just files or directories. Next I run a query of query to filter out just the images. Why not use the filter attribute? The cfdirectory tag only lets you filter by one extension. I wanted to support both GIFs and JPGs so I used the following:
<!--- filter out jpg and gif and _thumb_* --->
<cfquery name="images" dbtype="query">
select name
from images
where (lower(name) like '%.jpg'
or lower(name) like '%.gif')
and lower(name) not like '_thumb_%'
</cfquery>
Notice the last condition. I'm also going to filter out any file named thumb*. Why? I'm getting there.
Next I create a simple layout using the cflayoutarea tag, type=border. I'm not going to bother showing that code here, you can see it at the end. In my left hand menu I want to show all my pictures, but I want to show thumbnails and not a scaled down version of the full image. How do I do that?
<cfloop query="images">
<cfif not fileExists(folder & "_thumb_" & name)>
<cfimage source="#folder##name#" action="read" name="newimage">
<cfset imageScaleToFit(newimage, 100, 100)>
<cfimage action="write" source="#newimage#" destination="#folder#/_thumb_#name#" overwrite="true">
</cfif>
<cfoutput><a href="javaScript:setImage('#jsStringFormat(name)#');"><img src="#folderurl#/thumb#name#" border="0" vspace="5" /></a></cfoutput>
</cfloop>
I begin by looping over my images query. For each one, I check for the existence of a thumbnail version. If it doesn't exist, I read in the file using cfimage. I then use the scaleToFit function. This will resize and keep the proportions of my thumbnail. Lastly I write out the scaled down image. That last bit of JavaScript just sets the image for my main display.
Pretty simple, eh? As I said, I got a slightly sexier version to show tomorrow. Here is the complete code for the demo. Note that I abstracted out the URL and folder for images. In theory you could turn this into a simple custom tag.
<cfsetting showdebugoutput=false>
<!--- what url is the folder, relative from me --->
<cfset folderurl = "images2">
<!--- full path to folder --->
<cfset folder = expandPath("./images2/")>
<!--- get my images --->
<cfdirectory action="list" directory="#folder#" name="images" type="file">
<!--- filter out jpg and gif and thumb* --->
<cfquery name="images" dbtype="query">
select name
from images
where (lower(name) like '%.jpg'
or lower(name) like '%.gif')
and lower(name) not like 'thumb%'
</cfquery>
<cflayout type="border">
<cflayoutarea position="left" title="Pictures" size="150" align="center" collapsible="true">
<script>
function setImage(i) {
var mImage = document.getElementById('mainImage');
<cfoutput>
mImage.src='#folderurl#/'+i;
</cfoutput>
}
</script>
<cfloop query="images">
<cfif not fileExists(folder & "thumb" & name)>
<cfimage source="#folder##name#" action="read" name="newimage">
<cfset imageScaleToFit(newimage, 100, 100)>
<cfimage action="write" source="#newimage#" destination="#folder#/thumb#name#" overwrite="true">
</cfif>
<cfoutput><a href="javaScript:setImage('#jsStringFormat(name)#');"><img src="#folderurl#/thumb#name#" border="0" vspace="5" /></a></cfoutput>
</cfloop>
</cflayoutarea>
<cflayoutarea position="center" align="center">
<cfoutput>
<p>
<img src="#folderurl#/#images.name[1]#" id="mainImage">
</p>
</cfoutput>
</cflayoutarea>
</cflayout>