We help IT Professionals succeed at work.

using imageutil.cfc instead of cfimage

Last Modified: 2013-12-20
Hi exprets, i am using cfimage but it has a bug so my host have some issues in it. although i came accross the imageurtils code by bennadel. so i thought i should change my code and add some effctes like shadowing while i resize the imaage. but it is showing error while resizing.

Working with imageutils.cfc.
 before i used this tag, i was using cfimage tag
 to resize the image and store in the same location by overwriting:

> here i was
 doing it.
 <cfset inpoint = "#cffile.ServerFile#">
 <cfimage action="resize"
 width="#form.t2#" height="#form.t1#"
 destination="#request.file_path#\pictures\#Inpoint#" overwrite="yes">

 using imageutils.cfc, i modified it liked this:
<cfset imageutils = createObject("component", "#request.cfcPath#.imageUtils")>
my request.cfcPath eq to cfc folder
 <cfset inpoint =
 <cfset pic = imageread("pictures/#inpoint#")>
 newpoint= ImageNew(pic)>
 <cfset imageResize(newpoint,form.t2,form.t1) />
 <cfset latest = "#newpoint#">

 but it does not
 the image to same location rather it give this error:

 Error! Use
 GetReadableImageFormats() and GetWriteableImageFormats() to see which image
 formats are supported. The Image@19a60e1 image format is not supported on this
 operating system.
 I am trying to write the image to the same location where i
 had it before

 I want to use IMAGEUTILS.CFC because it has very nice features
 like drop shadow and i really want to play with it.
Watch Question

Dear CFer, ImageResize is a built in function of CF8 and so I am not sure why you need a CFC. Are you running older version of CF?

Refer to documentation of ImageResize:


There are many cool image functions in CF8: http://livedocs.adobe.com/coldfusion/8/htmldocs/functions-pt0_11.html#1099325
Also the error you are getting can be solved if you pass an image format that is supported by CF. Use this code:


what type of image is it you're trying to upload?  gif/jpeg/png etc?

also, looking at your code, I'm maybe misunderstanding, but generally AFAIK you need to refer the CFC when you try and call functions on that CFC (unless you're calling the functions from within the CFC itself).

i.e. I think the code should look more like this:

<cfset imageutils = createObject("component", "#request.cfcPath#.imageUtils")>
my request.cfcPath eq to cfc folder
 <cfset inpoint =
 <cfset pic = imageutils.imageread("pictures/#inpoint#")>
 newpoint= imageutils.ImageNew(pic)>
 <cfset imageutils.imageResize(newpoint,form.t2,form.t1) />
 <cfset latest = "#newpoint#">



my mistakes i corrected it a bit but still get the same error:

the attached is correct according to me.

imageread, imagenew are coldfusion build in functions used

now i crop it on two basis.

width, height, position like top, center, bottom. etc.

i want the cropped image to be written back to same folder and overwrite the original one, how can i do that.

the function aspectCrop is defined here:

<cfset imageutils = createObject("component", "#request.cfcPath#.imageUtils")>
				<cfset inpoint = "#cffile.ServerFile#">
                <cfset pic = imageread("pictures/#inpoint#")>
                <cfset newpoint= ImageNew(pic)>
                <cfset aspect = imageutils.aspectCrop(newpoint,form.t2,form.t1,form.position) />
                <cfset ImageWrite(aspect,"#request.file_path#\pictures\#aspect#")>
<cffunction name="aspectCrop" access="public" returntype="any" output="false" hint="">
		<!--- Define arguments. --->
		<cfargument name="image" type="any" required="true" hint="The ColdFusion image object or path to an image file." />
		<cfargument name="cropwidth" type="numeric" required="true" hint="The pixel width of the final cropped image" />
		<cfargument name="cropheight" type="numeric" required="true" hint="The pixel height of the final cropped image" />
		<cfargument name="position" type="string" required="true" default="center" hint="The y origin of the crop area." />
		<!--- Define local variables. --->
		<cfset var nPercent = "" />
		<cfset var wPercent = "" />
		<cfset var hPercent = "" />
		<cfset var px = "" />
		<cfset var ycrop = "" />
		<cfset var xcrop = "" />
		<!--- If not image, assume path. --->
		<cfif (
			(NOT isImage(arguments.image)) AND
			(NOT isImageFile(arguments.image))
			<cfthrow message="The value passed to aspectCrop was not an image." />
		<!--- If we were given a path to an image, read the image into a ColdFusion image object. --->
		<cfif isImageFile(arguments.image)>
			<cfset arguments.image = imageRead(arguments.image) />
		<!--- Resize image without going over crop dimensions--->
		<cfset wPercent = arguments.cropwidth / arguments.image.width>
		<cfset hPercent = arguments.cropheight / arguments.image.height>
		<cfif  wPercent gt hPercent>
			<cfset nPercent = wPercent>
    		<cfset px = arguments.image.width * nPercent + 1>
			<cfset ycrop = ((arguments.image.height - arguments.cropheight)/2)>
			<cfset imageResize(arguments.image,px,"") />
    		<cfset nPercent = hPercent>
    		<cfset px = arguments.image.height * nPercent + 1>
			<cfset xcrop = ((arguments.image.width - arguments.cropwidth)/2)>
			<cfset imageResize(arguments.image,"",px) />
		<!--- Set the xy offset for cropping, if not provided defaults to center --->
		<cfif listfindnocase("topleft,left,bottomleft", arguments.position)>
			<cfset xcrop = 0>
		<cfelseif listfindnocase("topcenter,center,bottomcenter", arguments.position)>
			<cfset xcrop = (arguments.image.width - arguments.cropwidth)/2>
		<cfelseif listfindnocase("topright,right,bottomright", arguments.position)>
			<cfset xcrop = arguments.image.width - arguments.cropwidth>
			<cfset xcrop = (arguments.image.width - arguments.cropwidth)/2>
		<cfif listfindnocase("topleft,topcenter,topright", arguments.position)>
			<cfset ycrop = 0>
		<cfelseif listfindnocase("left,center,right", arguments.position)>
			<cfset ycrop = (arguments.image.height - arguments.cropheight)/2>
		<cfelseif listfindnocase("bottomleft,bottomcenter,bottomright", arguments.position)>
			<cfset ycrop = arguments.image.height - arguments.cropheight>
			<cfset ycrop = (arguments.image.height - arguments.cropheight)/2>	
		<!--- Return new cropped image. --->
		<cfset ImageCrop(arguments.image,xcrop,ycrop,arguments.cropwidth,arguments.cropheight)>
		<cfreturn arguments.image>

Open in new window

This one is on us!
(Get your first solution completely free - no credit card required)
first of all, as someone has already said, Ben's ImageUtils.cfc uses same same built-in cf image functions and tags in it... so if your host has some problem with using cf8 built-in image functions/tags, switching to using ImageUtils.cfc will NOT solve your problem.

as for your latest question: all you need to do is replace the line
<cfimage action="writetobrowser" source="#aspect#"/>
<cfimage action="write" source="#aspect#" destination="full/path/to/your/pictures/folder/and/filename">

however, if i may make a wild guess, you host likely has a problem with what is known as "image-locking bug" in CF8, when after you manipulate your image, it gets locked and you can't overwrite it when trying to same altered image in the same location with same filename as original.

there are several solutions to this:
a) easy: ask your host to install the cfimage hotfix, which solves this issue. hotfix url: http://www.adobe.com/go/kb403411

[NOTE: cumulative hotfix 1 for CF8.0.1 was issued BEFORE the update to cfimage hotfix, and DOES NOT include the updated cfimage hotfix which solves the image-locking bug. If your host has only cumulative hotfix installed, they will need to install the updated cfimage hotfix too]

b) not so easy: use underlying java methods to write you image instead of using imagewrite() or <cfimage action="write" ...>. attached is a cffunction based on great work by cfSearching (http://cfsearching.blogspot.com/), which you can add to your copy of ImageUtils.cfc and then call that function when you need to write the image back to disk:
<cfset imageutils.ImageWriteReplacement(image, 'destination', quality)>
i.e. in your case something like this:
<cfset imageutils.ImageWriteReplacement(aspect, expandpath('/pictures/' & inpoint), 1)>


ImageWrite() CF8 function replacement by cfSearching, from
Work-around for CF8.0.1 image locking bug.
<cffunction name="ImageWriteReplacement" returns="void" access="public" output="false">
    <cfargument name="image" type="any" required="true" hint="ColdFusion image object to save">
    <cfargument name="destination" type="string" required="true" hint="Absolute path where you want to save the file">
    <cfargument name="quality" type="numeric" required="false" default="0.75" 
            hint="Image quality for jpg,jpeg images only. Fractional value between 0 and 1 (highest quality). Default is 0.75">
    <cfset var Local = {} >
    <cfset Local.extension = trim( listLast( arguments.destination, "." ) )>
    <cfset Local.buffered = imageGetBufferedImage( arguments.image )> 
    <cfset Local.outFile = createObject("java", "java.io.File").init( arguments.destination )>
    <cfset Local.imageIO = createObject("java", "javax.imageio.ImageIO")>
    <!--- confirm there is at least one registered writer for this image "format" --->
    <cfset Local.iter = Local.imageIO.getImageWritersByFormatName( Local.extension )>
    <cfif Local.iter.hasNext()>
        <cfset Local.writer = Local.iter.next()>
        <cfthrow message="No suitable image writers found for format: #Local.extension#">                     
    <!--- If this is a JPEG file ... --->
    <cfif listFindNoCase("jpg,jpeg", Local.extension)>
        <!--- set the image quality --->
        <cfset Local.param = Local.writer.getDefaultWriteParam()>
        <cfset Local.param.setCompressionMode( Local.param.MODE_EXPLICIT )>
        <cfset Local.param.setCompressionQuality( javacast("float", arguments.quality) )>
        <!--- create a stream for the output image file --->
        <cfset Local.outStream = createObject("java", "javax.imageio.stream.FileImageOutputStream").init( Local.outFile )>
        <cfset Local.writer.setOutput( Local.outStream )>
        <!--- convert the image to an IIOImage we can pass to the writer --->
        <cfset Local.image = createObject("java", "javax.imageio.IIOImage").init( Local.buffered , javacast("null", ""), javacast("null", "") )>
        <!--- save the image to disk and close the stream --->
        <cfset Local.writer.write( javacast("null", ""), Local.image, Local.param)>
        <cfset Local.outStream.close()>
        <cfset Local.imageIO.write( Local.buffered, Local.extension, Local.outFile )>

Open in new window



Thanks Azadi. i found it a resported Bug in Coldfusion. The way I solved it like :

using the getImageBytes undocumented feature and then in used fileWrite function to write the image to the same folder and it worked. My only concern is now that in the getimagebytes function. JPG extention is used. if there are more extentions then what to do here.
<input id="gwProxy" type="hidden"><!--Session data--><input onclick="jsCall();" id="jsProxy" type="hidden">
<cfset abytes = objImage.getImageBytes("jpg")> 

Open in new window

<cffile action="upload" returns a structure one of which members is ServerFileExt - extension of the uploaded file, without the . - you can use that in your code to assign proper extension to the saved file.

PS: using undocumented functions and features may turn into a problem when some next version of CF drops or renames the function/feature and your host upgrades their CF servers - you code will stop working.

using standard java classes/methods is unlikely to cause such a problem.



i understand your concern. current issue is with it will do with only jpg files. i have one idea, before it goes to the getimagebytes function why not convert every image upload to jpg. if already jpg skip conversion convert.

what you say
<input id="gwProxy" type="hidden"><!--Session data--><input onclick="jsCall();" id="jsProxy" type="hidden">
depending on the type of uploaded file, cf's built-in conversion can produce some rather horrible results... but then so may resizing and scaling functions, too...

iirc, cf can't write GIF images - it converts then to PNG automatically... or maybe that is only for writetobrowser action...

that ImageWriteReplacement function i posted before should deal with any uploaded image type (well, at least jpeg/gif/png, if i remember correctly...)


Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.