Art Site: cfimagination
Got the image stored in the database now, sweet. Next and final step is to get it back out. It's really as simple as resizing it to what I want and cfimage'ing it to the browser.
<cfset ImageResize(ArtImage,'','200')>
<cfset ImageAddBorder(ArtImage,2)>
<cfimage action="writeToBrowser" source="#ArtImage#" format="jpg">
This will resize the image to 200 pixels wide, give it a border, and write it to the browser as a jpg. But a few problems. What if it's a skinny bit of art? If it's only 150 pixels to start with and 800 pixels tall, I don't want to make it bigger. How do I set an alt tag to the img tag that. To solve some of these, I hit up my man Ben Nadel's blog, doing a search for "cfimage". I made some changes to his ImageWriteToBrowserCustom() function. In this version... The BORDER argument will add a border with Image functions, instead of styling the image. A watermark will be added if you want. The image size will be bound by the width and height given, rather than resizing to both arguments. And a little JavaScript will be added for later use.
access="public"
returntype="void"
output="true">
<cfargument name="Image" type="any" required="true" />
<cfargument name="Alt" type="string" required="false" default="" />
<cfargument name="Class" type="string" required="false" default="" />
<cfargument name="Style" type="string" required="false" default="" />
<cfargument name="Height" type="string" required="false" default="" />
<cfargument name="Width" type="string" required="false" default="" />
<cfargument name="Border" type="string" required="false" default="" />
<cfargument name="WaterMark" type="boolean" required="false" default="true" />
<cfargument name="Clickable" type="boolean" required="false" default="false" />
<cfset var LOCAL = {} />
<cfset LOCAL.myImage = ImageNew(ARGUMENTS.Image)>
<cfif arguments.width neq "" and LOCAL.myImage.getWidth() gt arguments.width>
<cfset ImageResize(LOCAL.myImage, arguments.width, "")>
</cfif>
<cfif arguments.height neq "" and LOCAL.myImage.getHeight() gt arguments.height>
<cfset ImageResize(LOCAL.myImage, "", arguments.height)>
</cfif>
<cfif arguments.Border neq "">
<cfset ImageAddBorder(LOCAL.myImage, arguments.border)>
</cfif>
<cfif arguments.WaterMark>
<cfset LOCAL.theWatermark = ImageNew(request.watermark)>
<!-- center the watermark at the bottom of the image -->
<cfset ImagePaste(LOCAL.myImage,
request.watermark,
(LOCAL.myImage.GetWidth() - LOCAL.theWatermark.GetWidth())/2,
(LOCAL.myImage.GetHeight() - LOCAL.theWatermark.GetHeight()))>
</cfif>
<!---
Write the image to the browser. This is really just
creating the image and then writing to the buffer.
All we have to do is intercept the buffer write.
--->
<cfsavecontent variable="LOCAL.Output">
<cfoutput>
<!--- Write image tag. --->
<cfimage
action="writetobrowser"
source="#LOCAL.myImage#"
format="jpg"
/>
</cfoutput>
</cfsavecontent>
<!---
First, delete any existing attributes that we might
be using (so that we can just add new ones).
--->
<cfset LOCAL.Output = LOCAL.Output.ReplaceAll(
"(?i) (alt|class|style|height|width|border)=""[^""]*""",
""
) />
<!---
Now that we have an image with Just the SRC
attribute, we can go about adding our attributes.
First, chop off the trailing slash.
--->
<cfset LOCAL.Output = LOCAL.Output.ReplaceFirst(
"\s*/?>\s*$",
""
) />
<!---
Loop over the arguments to see if we need to
add them to the tag.
--->
<cfloop
index="LOCAL.Key"
list="alt,class,style"
delimiters=",">
<!--- Check for a passed-in value. --->
<cfif Len( ARGUMENTS[ LOCAL.Key ] )>
<!---
Append this argument to the output and a
key-value attribute.
--->
<cfset LOCAL.Output &= (
" " &
LOCAL.Key &
"=""" &
ARGUMENTS[ LOCAL.Key ] &
""""
) />
</cfif>
</cfloop>
<cfif arguments.Clickable>
<cfset LOCAL.Output &= (
" onClick=""ColdFusion.Window.show('myImage')"""
) />
</cfif>
<!--- Write the image tag to the output. --->
<cfset WriteOutput( LOCAL.Output & " />" ) />
<!--- Return out. --->
<cfreturn />
</cffunction>
Blah blah blah, bunch of code. There's some easy enhancements that could be made but for the purposes of this project, they weren't needed. The watermark pulls from request.watermark, would be better if that were passed in. Would be nice if there were another argument to set if the resize is done as a bounding box or absolute resizing. This code assumes the image passed in will always be larger than what ends up being printed. Adding the watermark could be split into another function to tidy this up some. Should resize the watermark to fit the image given...
But using Ben's function, we now have an alt attribute on the image tag in the generated HTML, hurrah! Now I have very consistent image generation across the few pages that need it. To put in an image with a watermark, borders, alt tag, resized as needed...
<cfset createObject("component","jwa.model.udf").ImageWriteToBrowserCustom(
Image=ArtImage,
Alt="#request.artDetails.getArtTitle()#",
Border="2",
Width="300",
Clickable="true"
) />
The code that's added to the image tag if arguments.Clickable is true is fun. I needed something like "click here to enlarge". So I put a larger version of the image (same tag as above with larger dimensions) in a cfwindow called myImage. Would have been slicker to use some JavaScript library that I just copy/paste into place. But I've been doing Flex for so long, I wanted this project to be all CF and all code that I fully understand.
Doing all this reminds me of the pre-CF8 days (for me that was 2-3 weeks ago). I have an image.cfc sitting in my webroot that can do all sorts of stuff to images using Java voodoo space magic. cfimage takes away the need for most voodoo space magic, but still would be nice to build up a library of image functions. One for adding a watermark. One for resizing in a bounding box. One for a few image transformations I regularly do (resize, watermark, AND border)...

