Welcome!

Java Authors: Maureen O'Gara, Bruce Armstrong, Liz McMillan, Walter H. Pinson, III, Yakov Werde

Related Topics: ColdFusion, SYS-CON MEDIA

ColdFusion: Article

CFImage Functionality is Just Awesome!

Integration into Tag and Scripting Language is a Welcome Development

Here, not only are we converting the image from a JPG format to a GIF image format, we are also storing the image data into the ColdFusion 8 image object, objImage. This also demonstrates our next mode of image writing: writing the image directly to the browser.

Notice that to do this, I am specifying the source of the image (the image object we created) and the output format of JPG. The format attribute can be PNG, JPG, or JPEG but it defaults to PNG. Now, when I first saw this action, I had assumed it was working the same way CFContent worked - by streaming the file to the browser as the only returned content. However, WriteToBrowser actually returns the image inline to the page.

If you look at the source of the page with the rendered inline image, you will see something like this:

<img src="/CFFileServlet/_cf_image/_cfimg892407215213369995.jpg">

If I run that page a few times, I get a variety of different source values:

<img src="/CFFileServlet/_cf_image/_cfimg892407215213369995.jpg">
<img src="/CFFileServlet/_cf_image/_cfimg-6160259686183934424.jpg">
<img src="/CFFileServlet/_cf_image/_cfimg-9120958970657699225.jpg">
<img src="/CFFileServlet/_cf_image/_cfimg-5497181758516755239.jpg">

ColdFusion is actually writing your file to some sort of temporary image storage and then serving it up the way any other image or file would be served up. But what is CFFileServlet? If I look in the root of my ColdFusion 8 test account, there is no such directory. This is some sort of public mapping, but realize this - this is not a ColdFusion request; this is an image file request. Image file requests go the Web server, not the ColdFusion application server. I assume this means that in order for this to work, IIS (or which ever Web server you use) must have a mapping for CFFileServlet to some ColdFusion directory. This makes me nervous. I think it's an awesome feature, but I'm not sure I like having to rely on mappings and tying in with settings external to the ColdFusion application server.

On the flip side, however, I do like this for the very reason that the image request is not going to the ColdFusion server. Serving up images via ColdFusion's CFContent tag is relatively slow and puts a drain on the ColdFusion resources. Storing an image to a temp directly and then serving it using the Web server is going to be 10 times more efficient.

I would like to know more about how CFFileServlet works and specifically how often that directory is cleaned out. I don't want to start writing a lot of images to the browser only to find out that it is clogging up this temp directory. Unfortunately, this directory is not discussed in the ColdFusion 8 CFML Reference manual.

Images can also be written to disk after a variety of CFImage image manipulation actions, but for now, we are trying to stick to just straight up read/write, not manipulation.

When it comes to writing images using ColdFusion 8 image functions, there are basically two options: ImageWrite() and ImageWriteBase64(). ImageWrite() take three arguments (potentially):

  • Name: The name of the ColdFusion image object you are going to write.
  • Destination: The absolute or relative path name to which you are going to write the image. This argument is optional if the Source attribute of your image is available. For instance, if you read in the image locally via CFImage and then called ImageWrite() without a destination, it would overwrite the original image based on the internal Source. However, if you grabbed the image from a URL via CFImage, you must include a destination value with ImageWrite() as you cannot use the Source value (external URL) to store the image.
  • Quality: A value between 0 and 1 that can be used to set the JPG quality.

Reading an image from a URL and writing it to disk could be done this way:

<!--- Grab the image from the give source URL. --->
<cfimage
action="READ"
source="http://farm1.static.flickr.com/183/392739661_70619076b7.jpg"
name="objImage"
/>

<!--- Write the image to the disk. --->
<cfset ImageWrite(
objImage,
"./waterfall.jpg",
.75
) />

As you can see, since we are grabbing the image via a URL, we must include the destination value. I have also included the JPG quality value, but this was not necessary as that value defaults to .75.

ImageWriteBase64() writes ColdFusion images to text files using a Base64 encoding. It takes four arguments:

  • Name: The name of the ColdFusion image object that we are writing to disk.
  • Destination: Since the destination here is not an image but a text file, the destination is required (the internal Source of the image will not help us).
  • Format: This is the format of the image that we are going to encode. This is required, otherwise ColdFusion won't know which headers and conversion algorithm to include.
  • InHTMLFormat: This specifies how the data is going to be written to the text file. If you specify false (default) or omit the argument, the Base64 is written to the file without any headers. If you specify true, the Base64 encoding is written to the disk with HTML-style headers.

Here, we can modify our previous example to read from a URL and store to disk as a Base64-encoded JPG image:

<!--- Grab the image from the give source URL. --->
<cfimage
action="READ"
source="http://farm1.static.flickr.com/183/392739661_70619076b7.jpg"
name="objImage"
/>

<!--- Write the image to the browser. --->
<cfset ImageWriteBase64(
objImage,
"./waterfall.txt",
"JPG"
) />

Just a final note on paths; the Web-relative path (e.g., /lady.jpg) is relative to the currently executing Web page, not to the currently executing ColdFusion template. Therefore, if you are in an included template, you might get files stored in unexpected places if you don't fully grasp this concept.

Well, that's it. That's the quick(ish) overview on how you can read and write image files using ColdFusion 8's new CFImage tag and accompanying image functions. It's awesome that there is such a variety of input and output methodologies. Sorry that this went longer than intended, but this introduction only scratched the surface. ColdFusion's new image functionality is just plain awesome.

•   •   •

This article was reprinted with permission from Ben Nadel's blog:
www.bennadel.com/index.cfm?dax=blog:766.view.

More Stories By Ben Nadel

Ben Nadel has worked with ColdFusion for eight years and is a super ColdFusion enthusiast. He blogs regularly about all aspects of Web development on his personal site, http://www.bennadel.com, and does his best to give back to the ColdFusion community through online code demos and his "Ask Ben" blog posts. He is also a Certified Advanced ColdFusion MX7 developer and is one of the lead programmers at Nylon Technology.

Comments (3) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Michael 07/12/08 01:43:25 AM EDT

The noisy ad is beyond annoying.

Mike Ritchie 08/01/07 06:08:54 PM EDT

I wonder if the CF team consulted with the developer of ImageCFC? It also was basically a wrapper for the underlying Java image functionality. Either way, this looks like an exceptionally useful tool. Do you need to instantiate the object using cfimage? Or is it possible to manipulate an image completely within cfscript?

Sanjeev 07/15/07 10:07:34 PM EDT

rename the CodFusion as ColdFusion !