ColdFusion 8: URL Thumbnails

A reader asked me this morning if ColdFusion 8 can create images from URLs. This is often used to provide a snap shot of a remote site. Turns out this is relatively easy. Damon Cooper of Adobe showed an example of this a few weeks ago. It takes all of two tags:

<cfdocument src="http://www.coldfusionjedi.com" name="pdfdata" format="pdf" />
<cfpdf source="pdfdata" pages="1" action="thumbnail" destination="." format="jpg" overwrite="true" resolution="high" scale="25">

The first line simply uses cfdocument with the src attribute. I point to a URL (in this case, my blog) and store the result in a PDF variable.

Next I use the cfpdf tag to create a thumbnail. I specify the JPG format, use a high resolution, and set a scale to 25% just for the heck of it. Also note I only do page 1. By default the cfpdf/action="thumbnail" tag will create a thumbnail for each page of the PDF, but all we really want is the first page.

That's it. Done. Complete. Simple as pie. But of course I had to go a bit crazy and make a UDF out of it. The code below allows you to pass a URL (and an optional scale). It will then handle making the image, reading it into a CF8 Image object, deleting the file, and returning the object. You can then save it, or do whatever. For my tests, I did:

<cfset myimage = getThumbnail("http://www.coldfusionjedi.com",30)>
<cfimage action="writeToBrowser" source="#myimage#">

The "writeToBrowser" action lets me test without actually saving a file, but I believe it doesn't work in IE. (Not that I care.) Enjoy, and let me know how it works for you. I'll probably add options to let you specify an image type as well.

The image quality is pretty good I think. It is not the same as what you see from Firefox, but for a thumbnail, I think it works ok:

<cffunction name="getThumbnail" returnType="any" output="false">
   <cfargument name="url" type="string" required="true">
   <cfargument name="scale" type="numeric" required="false" default="25">
   
   <cfset var pdfdata = "">
   <cfset var prefix = replace(createUUID(),"-","_","all")>
   <cfset var myimage = "">
   
   <!--- make the pdf --->
   <cfdocument src="#arguments.url#" name="pdfdata" format="pdf" />
   
   <!--- write out the image --->
   <cfpdf source="pdfdata" pages="1" action="thumbnail" destination="." format="jpg" overwrite="true"
       resolution="high" scale="#arguments.scale#" imagePrefix="#prefix#">
   
   <!--- read it in --->
   <cfset myimage = imageNew(expandPath('./#prefix#_page_1.jpg'))>

   <!--- clean it up --->
   <cffile action="delete" file="#expandPath('./#prefix#_page_1.jpg')#">
   <cfreturn myimage>
</cffunction>

Comments

Scott Stroz's Gravatar What in the name of all that is holy is a 'snap snot'?
# Posted By Scott Stroz | 6/13/07 1:03 PM
Raymond Camden's Gravatar Dude I have no idea what you are talking about. (Whistles innocently)
# Posted By Raymond Camden | 6/13/07 1:06 PM
Damien McKenna's Gravatar Is the CFDocument generation of HTML any better than previous editions? IIRC it didn't support some/many CSS attributes.
# Posted By Damien McKenna | 6/13/07 1:56 PM
Damien McKenna's Gravatar Ray: idea for riaforge, automated application screenshots - give it a URL to where your app is set up as a demo, have it automatically grab a screenshot and store in the project. For a rainy day.
# Posted By Damien McKenna | 6/13/07 1:57 PM
Clark's Gravatar Cool! So maybe...then a Flash remoting CFC could take a screenshot of a site...and return that as a bytearray so it could be rendered in the Flash player? That would rock.
# Posted By Clark | 6/13/07 2:49 PM
David Harris's Gravatar great!
I've been wanting to be able to do that for ages!
BD has a "jpg" format on their cfdocument, I was hoping Adobe would think this was a good idea too!
# Posted By David Harris | 6/13/07 3:01 PM
Raymond Camden's Gravatar @Damien: I don't really know. I definitely saw oddities with my site being rendered - BUT - I could still read the site - I could still recognize it - so it was good enough I think.
# Posted By Raymond Camden | 6/13/07 3:09 PM
Dale Fraser's Gravatar Thanks Ray,

I knew if there was a way you would know how.

I think the quality is prety good, and while the CFDocument might not render every element perfectly, which browser does?

If you add in some IMAGE tags to dress up the final result, crop, put a border etc, would work well in lots of situations.
# Posted By Dale Fraser | 6/13/07 5:20 PM
Justin Lewis's Gravatar Nice solution. Just reading this, I have to wonder what the server cpu overhead would be if you are running that on every load. Maybe doing it once and saving the image if NOT fileExists.

I'll try it out and check out how much megahurtz it steels.
# Posted By Justin Lewis | 6/13/07 10:12 PM
Raul Riera's Gravatar Great, this should be a new question on the coldfusion cookbook
# Posted By Raul Riera | 6/14/07 7:57 AM
Tom Jordahl's Gravatar Note that the writetobrowser action now writes the file to a disk cache and emits an img tag that references the CF file caching servlet.

Should work in any browser.
# Posted By Tom Jordahl | 6/14/07 3:44 PM
Raymond Camden's Gravatar Thanks Tom. I wasn't sure about the IE thing.
# Posted By Raymond Camden | 6/14/07 3:48 PM
Dwayne Anderson's Gravatar why would the src attribute not be available to me

error:Attribute validation error for tag CFDOCUMENT.
# Posted By Dwayne Anderson | 6/20/07 5:02 PM
Raymond Camden's Gravatar You are using CF8, right?
# Posted By Raymond Camden | 6/20/07 5:06 PM
Dwayne Anderson's Gravatar MX7 - damn, soes this mean it does not work...I've been struggling with this for 2 days.
# Posted By Dwayne Anderson | 6/20/07 5:16 PM
Dwayne Anderson's Gravatar but even in Dreamweaver 8, the attribute doesn't show up. ) i have CFMX7 on the server and 8 on my machine.
# Posted By Dwayne Anderson | 6/20/07 5:18 PM
Raymond Camden's Gravatar Correct. Sorry. FYI, to make it work with DWMX8, I mean the editing, you need to get the updated tag library from labs. I believe. I'm not a DW users. (*cough*CFEclipse*cough*)
# Posted By Raymond Camden | 6/20/07 5:22 PM
BL's Gravatar Wow, that's really cool. I didn't even think about the possibilities of a format="jpg" on the cfpdf tag. Good call Adobe.
# Posted By BL | 7/9/07 10:47 PM
Dave Phipps's Gravatar What css media type does cfdocument use/recognise. I use a media type of screen and all I see is an unstyled page in the my thumbnail. Try pointing your code to: www.abingdon.org.uk
# Posted By Dave Phipps | 7/11/07 7:52 AM
CV's Gravatar Ray, when I use your code, some thumbs have missing "sections" in them (they are blank or white). It seems that Flash does not get rendered in the thumbnail either. It also seems that some photos on simple HTML do not get rendered as well. Any idea as to why or how to improve on the accuracy of the "grab"? Thanks!

Here are a few sample URLs that get a little funky:
http://www.caraccessories.com/
http://www.partstrain.com/

Is this worthy of another blog entry?
# Posted By CV | 9/3/07 3:07 PM
Raymond Camden's Gravatar That is all done behind the scenes. You would need to talk to Adobe about that.
# Posted By Raymond Camden | 9/4/07 1:55 PM
Brett's Gravatar Ray, when you say talk to adobe, is there a specific place to go to talk to them. I have a whole series of PDF files that when I run the code, like CV stated above, I get nothing but a JPG with a blank page. After a day of searching and trying different work-arounds, I still can't seem to get this to work correctly. By the way, your site is by far the best CF 8 resource I have found. Thank you.
# Posted By Brett | 9/17/07 10:44 AM
Raymond Camden's Gravatar You have two choices.

One is support. I don't know if that is free or not. I've only ever called support when I needed help with my CS3 install (oh god, the pain, the pain!). You would use that option if you need something fixed now.

If you just want to file a bug report, then go to www.adobe.com/go/wish. You can also use that URL to request a new feature.
# Posted By Raymond Camden | 9/17/07 10:48 AM
Solomon's Gravatar Please can someone tell me if it is possible to possible to create a PDF with updateable fields, then use ColdFusion & pdf forms to merge the data.
# Posted By Solomon | 10/1/07 3:22 AM
Doug Jones's Gravatar For those of you that are wondering why the thumbnail doesn't look 100% like your browser window rendering, I think cfpdf reads your page like it would look if you were to print it. So it's not going to look 100% like your browser window unless you have created a stylesheet for media type "print".

At least that's been my observation. Still very cool.
# Posted By Doug Jones | 4/22/08 2:52 PM
Mike's Gravatar Hey Ray,

I just tried this, and using the exact code in your eg there im seeing this exception

writeToBrowser:


coldfusion.image.Image$ReadImageMetadataException: Unable to read image source properly. D:\Domains\xxxxxx.com\wwwroot\0DBCEC5F_19B9_F849_B29064C59F3AC984_page_1.jpg (The system cannot find the file specified)

any ideas why this wouldnt work?
# Posted By Mike | 8/29/08 4:16 AM
Raymond Camden's Gravatar Interesting. It definitely worked before. This is an old blog entry, so it must be something that changed in 801.
# Posted By Raymond Camden | 8/30/08 9:53 AM
Raymond Camden's Gravatar Ok, I got it fixed. Just change the last line of the UDF to:

<cfreturn imageGetBlob(myimage)>

This makes the UDF return the binary data of the image, not a 'native cf image' which is barfing when you try to use it. It barfs because we delete the original temp source we used. As I said, something must have changed in 801.

Anyway, the binary data CAN be used with writeToBrowser, or you can save it, whatever. Either way, it's fixed now.
# Posted By Raymond Camden | 8/30/08 10:04 AM
Jeff Horne's Gravatar I know this is late in the game on this topic but is there any reason the site image can not be placed in a cftooltip tag so the user will see the image in a tooltip box before clicking on the actual link. This would avoid having to use some of the ad supported apps like <a href="http://www.snap.com">Snap Shots</a>.
# Posted By Jeff Horne | 9/11/08 9:38 AM
Raymond Camden's Gravatar You can do it - if you do an IMG tag pointing to a CFM that makes the snapshot. What you have to watch out for is speed. You would definitely want to cache your snapshots.
# Posted By Raymond Camden | 9/11/08 9:40 AM
Tim Mortimer's Gravatar Hi Ray

Always find your blogs useful. A related question to this thread - whats the easiest way to convert CFML output or text to an image in CF?

Tim
# Posted By Tim Mortimer | 9/14/08 4:36 PM
Raymond Camden's Gravatar Check the CF8 docs for imageDrawText()
# Posted By Raymond Camden | 9/14/08 9:12 PM
Freemont's Gravatar Was having trouble with creating thumbnails from a pdf with cfpdf. Looked at this site, than I found that saving the pdf to Acrobat 8, than running the code, rendered the pdf correctly.
# Posted By Freemont | 2/6/09 12:20 PM