Solved

using imageutil.cfc instead of cfimage

Posted on 2009-05-07
11
1,024 Views
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#"
 source="#request.file_path#\pictures\#Inpoint#"
 destination="#request.file_path#\pictures\#Inpoint#" overwrite="yes">

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

 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.
0
Comment
  • 4
  • 4
  • 2
  • +1
11 Comments
 
ID: 24328557
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:

http://livedocs.adobe.com/coldfusion/8/htmldocs/functions_h-im_39.html#5171309

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

<cfoutput>#GetReadableImageFormats()#</cfoutput>

0
 
LVL 16

Expert Comment

by:duncancumming
ID: 24328599
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 =
 "#cffile.ServerFile#">
 <cfset pic = imageutils.imageread("pictures/#inpoint#")>
 <cfset
 newpoint= imageutils.ImageNew(pic)>
 <cfset imageutils.imageResize(newpoint,form.t2,form.t1) />
 <cfset latest = "#newpoint#">
 <cfset
imageutils.ImageWrite(latest,"#request.file_path#\pictures\#latest#")>

0
 
LVL 15

Author Comment

by:Gurpreet Singh Randhawa
ID: 24328976
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." />

		</cfif>

		

		<!--- 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) />

		</cfif>
 

		<!--- 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,"") />

		<cfelse>

    		<cfset nPercent = hPercent>

    		<cfset px = arguments.image.height * nPercent + 1>

			<cfset xcrop = ((arguments.image.width - arguments.cropwidth)/2)>

			<cfset imageResize(arguments.image,"",px) />

		</cfif>
 

		<!--- 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>

		<cfelse>

			<cfset xcrop = (arguments.image.width - arguments.cropwidth)/2>

		</cfif>

		

		<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>

		<cfelse>

			<cfset ycrop = (arguments.image.height - arguments.cropheight)/2>	

		</cfif>	
 

		<!--- Return new cropped image. --->

		<cfset ImageCrop(arguments.image,xcrop,ycrop,arguments.cropwidth,arguments.cropheight)>

		

		<cfreturn arguments.image>

	</cffunction>

Open in new window

0
 
LVL 15

Accepted Solution

by:
Gurpreet Singh Randhawa earned 0 total points
ID: 24329556
okay i changed a bit see what exactly is happening.

it generates the output very perfectly, only thing is instead of writing on the browser i want the image to be stored in my pictures folder from where it was picked up and overwrite should be set to yes

<cfset form.inpoint = "#inpoint#">

              	<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 objWatermark = ImageNew("pictures/watermark.png")/>

                <cfset ImageSetAntialiasing(aspect,"on") />

                <cfset ImageSetDrawingTransparency(aspect,50) />

                <cfset ImagePaste(aspect,objWatermark,(aspect.GetWidth() - objWatermark.GetWidth()),(aspect.GetHeight() - objWatermark.GetHeight())) />

                <cfimage action="writetobrowser" source="#aspect#"/>

Open in new window

0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 27

Expert Comment

by:azadisaryev
ID: 24332517
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#"/>
with
<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)>

hth

Azadi
<!--- 

ImageWrite() CF8 function replacement by cfSearching, from

http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=1&catid=7&threadid=1358449.

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()>

    <cfelse>

        <cfthrow message="No suitable image writers found for format: #Local.extension#">                     

    </cfif>     

    <!--- 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()>

    <cfelse>

        <cfset Local.imageIO.write( Local.buffered, Local.extension, Local.outFile )>

    </cfif>

</cffunction>

Open in new window

0
 
LVL 15

Author Comment

by:Gurpreet Singh Randhawa
ID: 24332728
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

0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 24332814
<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.

Azadi
0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 24332822
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.

Azadi
0
 
LVL 15

Author Comment

by:Gurpreet Singh Randhawa
ID: 24332832
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">
0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 24335014
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...)

Azadi
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

CFGRID Custom Functionality Series -  Part 1 Hi Guys, I was once asked how it is possible to to add a hyperlink in the cfgrid and open the window to show the data. Now this is quite simple, I have to use the EXT JS library for this and I achiev…
I spent nearly three days trying to figure out how incorporate OAuth in Coldfusion for the Eventful API. Hopefully, this article will allow Coldfusion Programmers to buzz through the API when they need to. Basically, what this script does is authori…
The purpose of this video is to demonstrate how to properly insert a Vimeo Video into a WordPress site or Blog. This will be demonstrated using a Windows 8 PC. Go to your WordPress login page. This will look like the following: mywebsite.com/wp…
The purpose of this video is to demonstrate how to set up basic WordPress SEO. This will be demonstrated using a Windows 8 PC. The plugin used will be WordPress SEO by Yoast. Go to your WordPress login page. This will look like the following: myw…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now