Raymond Camden's Blog Rss

ColdFusion 8: URL Thumbnails

48

Posted in ColdFusion | Posted on 06-13-2007 | 12,339 views

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:

view plain print about
1<cfdocument src="http://www.coldfusionjedi.com" name="pdfdata" format="pdf" />
2<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:

view plain print about
1<cfset myimage = getThumbnail("http://www.coldfusionjedi.com",30)>
2<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:

view plain print about
1<cffunction name="getThumbnail" returnType="any" output="false">
2    <cfargument name="url" type="string" required="true">
3    <cfargument name="scale" type="numeric" required="false" default="25">
4    
5    <cfset var pdfdata = "">
6    <cfset var prefix = replace(createUUID(),"-","_","all")>
7    <cfset var myimage = "">
8    
9    <!--- make the pdf --->
10    <cfdocument src="#arguments.url#" name="pdfdata" format="pdf" />
11    
12    <!--- write out the image --->
13    <cfpdf source="pdfdata" pages="1" action="thumbnail" destination="." format="jpg" overwrite="true"
14         resolution="high" scale="#arguments.scale#" imagePrefix="#prefix#">

15    
16    <!--- read it in --->
17    <cfset myimage = imageNew(expandPath('./#prefix#_page_1.jpg'))>
18
19    <!--- clean it up --->
20    <cffile action="delete" file="#expandPath('./#prefix#_page_1.jpg')#">
21    <cfreturn myimage>
22</cffunction>

Comments

[Add Comment] [Subscribe to Comments]

What in the name of all that is holy is a 'snap snot'?
Dude I have no idea what you are talking about. (Whistles innocently)
Is the CFDocument generation of HTML any better than previous editions? IIRC it didn't support some/many CSS attributes.
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.
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.
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!
@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.
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.
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.
Great, this should be a new question on the coldfusion cookbook
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.
Thanks Tom. I wasn't sure about the IE thing.
why would the src attribute not be available to me

error:Attribute validation error for tag CFDOCUMENT.
You are using CF8, right?
MX7 - damn, soes this mean it does not work...I've been struggling with this for 2 days.
but even in Dreamweaver 8, the attribute doesn't show up. ) i have CFMX7 on the server and 8 on my machine.
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*)
Wow, that's really cool. I didn't even think about the possibilities of a format="jpg" on the cfpdf tag. Good call Adobe.
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
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?
That is all done behind the scenes. You would need to talk to Adobe about that.
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.
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.
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.
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.
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?
Interesting. It definitely worked before. This is an old blog entry, so it must be something that changed in 801.
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.
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>.
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.
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
Check the CF8 docs for imageDrawText()
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.
Its not working in cf9
error :
An error: ERROR encountered loading http://www.xxxx.com/: java.net.ConnectException: Connection timed out: connect occured during the rendering process of this document.
Works fine in cf8 but getting Connection timed out error using cf9 what to do??
Are you sure the machine can hit the URL at all? Try a simple test w/ cfhttp.
when i tried to call the url using cfhttp in cf9 i got dis result
but is working fine in cf8
Charset     [empty string]
ErrorDetail    Connect Exception: Connection timed out: connect
Filecontent    Connection Failure
Header    [empty string]
Mimetype    Unable to determine MIME type of file.
Responseheader    
struct [empty]
Statuscode    Connection Failure. Status code unavailable.
Text    YES

any other method of creating thumbnail without using cfdocument and cfpdf ??
Interesting - what's the URL again?
Tried to call the url as given. It worked fine in CF8

<cfhttp
timeout="120"
throwonerror="false"
url="http://www.barclaybrowning.com";
method="get"
useragent="Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12"
getasbinary="yes"
result="pdfdata"
>
This, to me, sounds like a DNS issue. Are the CF8 and CF9 servers on the same physical box? If not - try this. RDP to the box. Open a browser. And then try to hit the URL. If it fails, it means your box can't reach the remote URL. Check your network settings.
Ok thanks.. will try it
Please check the link
http://testw.wineweb.com/webshot/index.cfm
My site jibuas.com
But
4cornerswinery.com
adastrawines.com
amethystwines.com
avanguardiawines.com
etc...
not working
You miss my point. It doesn't matter if it works for me. If your server can't hit those URLs, it is a network issue on the box. The fact that some other tool (webshot?) also fails seems to imply the same.
Wow! Much better than the buggy CFX tag I was using before! Thank you!
Another url that gets funky httpp://www.barretire.com
<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">

Railo seems to require # # around pdfdata when set as source in cfpdf.
Ray great sample. I was wondering if you had a suggestion how to possibly postpone the the thumbnail snap shot until the page is fully loaded. Thanks
If you are talking about things that happen via JS or otherwise, then no, that can't be done.

[Add Comment] [Subscribe to Comments]