Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

using imageutil.cfc instead of cfimage

Posted on 2009-05-07
11
Medium Priority
?
1,055 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

 
LVL 16

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 16

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

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 16

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

Supports up to 4K resolution!

The VS192 2-Port 4K DisplayPort Splitter is perfect for anyone who needs to send one source of DisplayPort high definition video to two or four DisplayPort displays. The VS192 can split and also expand DisplayPort audio/video signal on two or four DisplayPort monitors.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What You Need to Know when Searching for a Webhost Provider
Dramatic changes are revolutionizing how we build and use technology. Every company is automating, digitizing, and modernizing operations. We need a better, more connected way to work together as teams so we can harness the insights from our system…
The purpose of this video is to demonstrate how to make a WordPress Site faster and smaller in size by cleaning up the database. This will be demonstrated using a Windows 8 PC. Plugin WP Optimize will be used. Go to your WordPress login page. T…
The purpose of this video is to demonstrate how to integrate Mailchimp with WordPress, by placing a Mailchimp signup form on a WordPress Page or Post. This will be demonstrated using a Windows 8 PC. Mailchimp will be used. Log into your Mailchi…

722 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