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>
Archived Comments
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.
Better now than never Che. :)
What really concerns me is how well that alligator gets along with those kittens. Your reptile training skills must be amazing!
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?
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.
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.
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.
KITTENS!
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.
Dave, please find my blog entry after my last presentation on cfimage. I have sample code in there just for that.
Ray,
I can't seem to locate it. If it is in your new book, i will see it there.
Thanks,
Dave
Here ya go:
http://www.coldfusionjedi.c...
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.
Crime story? Now ou have to share the link.
Now you need to make it cycle automatically. Or is that in the "sexier" version? (Which I guess I should go look for)
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
What do you mean by unit? Do you mean another drive? If it's on the same box, it should just work.
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 ??
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.
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>
Instead of expandPath - just use the 'real' directory.
Thanks a lot Raymond, it works.
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 ?
"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.
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!
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.
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:
Err, right. They don't work because - as I said - it is a web server setting, not a server setting.
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
You could do this by using cfhttp to get the html and then regular expressions to parse the html.
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
Eh? It isn't secured. This worked fine for me:
<cfhttp url="http://www.bbc.com">
<cfdump var="#cfhttp#">