Simple image slide show built in ColdFusion 8

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:

Demo

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>

Archived Comments

Comment 1 by Che posted on 8/30/2007 at 3:49 AM

imageScaleToFit??? I can't believe I did not see that in the docs. Ugh! I've been using a bit of 9th grade algebra and then cfimage's resize function to maintain proportions when only a width is specified.

My algebra went like this:
<cfset resizedHeight = round((resizedWidth * objImage.Height) / objImage.Width) />

imageScaleToFit will be a lot easier. I knew there had to be a function for this.

Comment 2 by Todd Rafferty posted on 8/30/2007 at 4:17 AM

Better now than never Che. :)

Comment 3 by Steven Erat posted on 8/30/2007 at 4:23 AM

What really concerns me is how well that alligator gets along with those kittens. Your reptile training skills must be amazing!

Comment 4 by Che posted on 8/30/2007 at 5:11 PM

You know, I wonder why proportional resizing with only the width or height was not built in to the <cfimage> tag?

Anyone have any ideas why a separate CF function had to be created to accomplish this?

Comment 5 by Raymond Camden posted on 8/30/2007 at 5:16 PM

Che:
I do not propose to speak for Adobe, but this is my take.

The cfimage tag was built to do "common" functions. Not everything. So adobe made choices on what would make sense in there.

Outside of that - everything (*) cfimage can do can be done in image functions.

When I say everything, I mean everything but writeToBrowswer, and while CAPTCHA can be done with functions, it is a heck of a lot easier with cfimage.

Comment 6 by Dave Dugdale posted on 8/30/2007 at 6:12 PM

Ray,

I think this is why your web site is so great - you provide lots of examples - please keep the CF8 examples coming.

I would love to see what Coldfusion can do with an image uploading interface.

I am waiting for your and Ben's new book to come out.

Comment 7 by Raymond Camden posted on 8/30/2007 at 6:16 PM

Thanks for the compliments. In regards to your second paragraph, are you asking for a simple image upload demo? Ie, how to handle someone uploading an image - ensuring it is an image - checking size - etc.

Comment 8 by Jamie Samland posted on 8/30/2007 at 6:17 PM

KITTENS!

Comment 9 by Dave Dugdale posted on 8/30/2007 at 6:39 PM

Ray,

Yes, I would love to see a simple image upload demo in CF8!

I created my own image uploader for my rental site in CF7 using Doug Hugh's CFC but I would love to see what the new image tag can do.

Comment 10 by Raymond Camden posted on 8/30/2007 at 6:43 PM

Dave, please find my blog entry after my last presentation on cfimage. I have sample code in there just for that.

Comment 11 by Dave Dugdale posted on 8/30/2007 at 7:23 PM

Ray,

I can't seem to locate it. If it is in your new book, i will see it there.

Thanks,
Dave

Comment 12 by Raymond Camden posted on 8/30/2007 at 7:27 PM
Comment 13 by Ben posted on 1/23/2008 at 11:50 PM

Thanks for posting this code. Though simple, it's just what I needed to post some photos of a local crime story. Thank you, thank you.

Comment 14 by Raymond Camden posted on 1/23/2008 at 11:55 PM

Crime story? Now ou have to share the link.

Comment 15 by Don posted on 9/24/2009 at 11:56 PM

Now you need to make it cycle automatically. Or is that in the "sexier" version? (Which I guess I should go look for)

Comment 16 by ulises posted on 8/22/2012 at 2:52 AM

Hi Raymond, can you tell me, how can i read a directory from another unit ?? for example i want to list the files locate in D:\My Unit D.

thanks Raymond

Comment 17 by Raymond Camden posted on 8/22/2012 at 5:39 AM

What do you mean by unit? Do you mean another drive? If it's on the same box, it should just work.

Comment 18 by ulises posted on 8/22/2012 at 7:58 PM

yeah i need to put a link to an absolute path, outside the wwwroot, for example G:/Documents/images/ because i use for the moment a pendrive for my images, but i can´t, i read something about mappings, but when i scan the server, i have the next problem "IO error on server communication", im lost can u help me ?? exists another solution ??

Comment 19 by Raymond Camden posted on 8/22/2012 at 9:16 PM

Um, well first off, you need to ensure you can see the images via your browser first. You need to add a virtual directory in your web server. How you do that depends on the web server you are using.

Comment 20 by ulises posted on 8/22/2012 at 10:41 PM

im using the built in ColdFusion Web Server, i added a virtual mapping in jrun-web.xml:

<virtual-mapping>
<resource-path>/sibapro-ulises/sfp2012/*</resource-path>
<system-path>F:/Clase14deJulio</system-path>
</virtual-mapping>

so now i can see my files of the pendrive (F:) in the browser with:

http://localhost:8500/sibapro-ulises/sfp2012/

now the problem is that i want to make a list of links to my files using ExpandPath, but i cant...

i was using ExpanPath for my files in wwwroot but now not works

the value of #URL.rutacat# is http://localhost:8500/sibapro-ulises/sfp2012/

<cfdirectory action="list" directory="#ExpandPath('#URL.rutacat#/CAT/')#" name="loglist">
<cfoutput query="loglist">
<a href=" #URL.rutacat#/CAT/#name#">#name#</a>

#size#
<br />
</cfoutput>

Comment 21 by Raymond Camden posted on 8/23/2012 at 12:25 AM

Instead of expandPath - just use the 'real' directory.

Comment 22 by ulises posted on 8/23/2012 at 12:33 AM

Thanks a lot Raymond, it works.

Comment 23 by ulises posted on 8/23/2012 at 7:41 PM

sorry raymond i think that it works but i am wrong, can u help me ?

sfp2012 its my virtual mapping. If i put:

http://localhost:8500/sibapro-ulises/sfp2012/ in my browser it works, i see my files of the pendrive (F:).

But if i put in my cfdirectory:

<cfdirectory directory="http://localhost:8500/sibapro-ulises/sfp2012/" name="loglist" >

i cant see anything, so i try with the absolute path in cfdirectory:

<cfdirectory directory="F:\Clase14deJulio\00009083-004-11\CAT" name="loglist" >

And it works, i see the files of my pendrive (F:), But i can´t make a link to these files, i can´t open any files !, only see it

<cfoutput query="loglist">
<a href="F:\Clase14deJulio\00009083-004-11\CAT\#loglist.name#">#loglist.name#</a>
</cfoutput>

In resume i think that, why i can not make a link to an absolute path ?

Comment 24 by Raymond Camden posted on 8/23/2012 at 7:44 PM

"i can't make a link to these files"
Are you talking about an HTML link? If so, sure you can. Your CFDIRECTORY call is returning the file names. You know the URL path to your files, it is /sfp2012. So the link is just /sfp2012/#name# where name is the filename.

Comment 25 by ulises posted on 8/23/2012 at 8:47 PM

ok, i do the next thing raymond and it works

in my cfdirectory i put the absolute path (for some reason if i put the "virtual map" not works)

<cfdirectory directory="F:\Clase14deJulio\00009083-004-11\CAT" name="loglist" >

and in my href (yes an html link) I put the virtual map
<a href="sfp2012/#loglist.name#">#loglist.name#</a>

and It works

thanks again Raymond!

Comment 26 by Raymond Camden posted on 8/23/2012 at 8:50 PM

Just to help you understand why the virtual directory didn't work in CFDIRECTORY - remember that the virtual directory is a web server setting. ColdFusion knows nothing about that.

Comment 27 by ulises posted on 8/23/2012 at 9:26 PM

i dont know raymond, i try in <cfdirectory with

sfp2012 and not works

<cfdirectory directory="sfp2012" name="loglist" >

i try also with:

/sfp2012
./sfp2012
\sfp2012

the result its the same, i can not list the files in F:

Comment 28 by Raymond Camden posted on 8/23/2012 at 9:30 PM

Err, right. They don't work because - as I said - it is a web server setting, not a server setting.

Comment 29 by santosh kodidasu posted on 6/12/2013 at 2:29 PM

Using the ColdFusion , can we show all the images available on a particular website for eg : http://www.bbc.com
and also count occurence of every letter in source code of any website

Comment 30 by Raymond Camden posted on 6/12/2013 at 3:44 PM

You could do this by using cfhttp to get the html and then regular expressions to parse the html.

Comment 31 by santosh kodidasu posted on 6/12/2013 at 4:06 PM

If I use cfhttp , I am getting the following response . Is it because of the security on this website http://www.bbc.com

struct
Charset [empty string]
ErrorDetail Unknown host: www.bbc.com: www.bbc.com
Filecontent Connection Failure
Header [undefined struct element]
Mimetype Unable to determine MIME type of file.
Responseheader struct [empty]

Statuscode Connection Failure. Status code unavailable.
Text YES

Comment 32 by Raymond Camden posted on 6/12/2013 at 4:10 PM

Eh? It isn't secured. This worked fine for me:

<cfhttp url="http://www.bbc.com">
<cfdump var="#cfhttp#">