Frage

Possible Duplicate:
Why should I resize an image in Coldfusion if the file size doen't decrease and the quality of the image suffers?

I must be doing something wrong here... using Coldfuison8

I have a product search which is pulling in images from external servers, so I need to set images on runtime.

Say I have a jpg 500x500px 111kb, which I'm grabbing from the external server.

Right now I'm doing this:

<cfimage name="myImage" source="#bildpfad##bilddateiname#" action="read" />
<cfif IsImage(myImage) is true>
    <cfscript>
    ImageSetAntialiasing(myImage,"on");
    variables.breite = 400;
        ImageScaleToFit(myImage, variables.breite,"", "highestPerformance");
    </cfscript>
<cfxml variable="imageXml">
    <cfimage action="writetobrowser" source="#myImage#" />
</cfxml>
<cfoutput><div class="resultsImgWrap">#imageXml#</div></cfoutput>

This displays the image allright, but when I check the filesize, I have

400x400px 111.2kB

If I use IrfanView for example and just reduce the filesize and save the image, I'm already at 65kb.

Question: How can I make CFIMAGE reduce the file size if I'm resizing the image? If the size stays at 111kb, why use CFIMAGE at all and not simply add the image as plain HTML.

**EDIT'':
The variables Bildpfad and Bilddateiname will be something like:

bildpfad (path to image):         http://www.some-server.com/images/
bilddateiname (filename):         some_image123.jpg
War es hilfreich?

Lösung

Specify the quality attribute in <cfimage>. I'm not sure if it works with action="writeToBrowser", but it should. Otherwise, file a bug report.

Resize and Compression are different things. :)

See: Why should I resize an image in Coldfusion if the file size doen't decrease and the quality of the image suffers?

UPDATE

Good news, there's an undocumented way to get it working! See: http://www.bennadel.com/blog/2405-Using-The-Quality-Attribute-With-The-CFImage-WriteToBrowser-Action.htm

<!--- Write out as a JPG at 20% (using "quality" attribute). --->
<cfimage
    action="writeToBrowser"
    source="#png#"
    format="jpg"
    quality=".2"
    />

Andere Tipps

Resizing an image it not intended to make the file size smaller in bytes. It is to make it smaller by height and width. Yes, more often than not the image file size does become smaller. But that size reduction depends on the source image.

You might want to declare the format as png as that may help make the file smaller.

Also, why are you wrapping the cfimage tag in cfxml? That is a useless step that is causing extra processing and bloat.

The use of 'action="writetobrowser"' will use a copy of the source image. It creates a temporary file that is pushed to the browser and destroyed later.

Here is a phrase from the CF 8 docs:

"Use the writeToBrowser action to display one or more ColdFusion images directly to the browser without writing them to files."

I tested your code with CF8 with a large photo (4608x3456) @ 3.47MB. The image that was displayed on my browser was resized to 400x300 @ 247.47KB. I used the Firefox right-click | View Image Info to get the resized image info. You can also use the Firebug | Net tab to get the transmitted image size.

The resized image will be in "/CFFileServlet/_cf_image/".

The size of the original file (#bildpfad##bilddateiname#) will not change.

Don't rely on the existence of a file that is designed to be temporary. Temporary means just that. The file name from one resize may not be the same filename on a resize 10 minutes later even though it is the same source image. Temporary files may be handled differently between different versions of CF as well.

If you need to keep a copy of the resized image, use action="write" or action="resize" with a destination attribute and save a copy of the resized image on the CF server.

Here is a sample of how it could work:

<!---assume that bildpfad can be different domains/folders--->
<!---RegEx = remove protocol, replace '/' with '!',  replace '.' with '~'--->
<cfset slashReplacement = "!">
<cfset periodReplacement = "~">
<cfset imageFilename = REReplace(REReplace(REReplaceNoCase(bildpfad, "https?://", "", "one"), "\/", slashReplacement, "all"), "\.", periodReplacement, "all") & bilddateiname>
<!---resizedImgDestination is a web path--->
<cfset resizedImgDestination = "/images/resized/rs_#imageFilename#">
<!---debug info, can comment out when working--->
<cfoutput>source = [#bildpfad##bilddateiname#]<br />destination = [#ExpandPath(resizedImgDestination)#]<br /></cfoutput>
<!---/debug info, can comment out when working--->
<cfif NOT FileExists(ExpandPath(resizedImgDestination))>
    <cfhttp url="#bildpfad##bilddateiname#" result="stGetImg" resolveurl="no" useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1" timeout="45" getasbinary="yes" throwonerror="no" />
    <cfset myImage = ImageNew(stGetImg.FileContent)>
    <cfif IsImage(myImage)>
        <cfimage action="resize" destination="#ExpandPath(resizedImgDestination)#" height="" isbase64="false" overwrite="true" source="#myImage#" width="400" />
    </cfif>
</cfif>
<cfoutput><img src="#resizedImgDestination#" /></cfoutput>

By leaving height as an empty string, it will resize and scale the height to match the width proportionally.

You will have to create '/images/resized/' folder from your sites web root.

ExpandPath() is better than using static path definitions. If you ever have to move a site to a different server or OS it will save a lot of time.

Note: I updated the code above to better fit the use of the variables in the question. I also changed how the image was read. I have CF 8.01 with CHF 4 + Hotfixes installed, but I got an error (Exception occured in JPG processing. segment size would extend beyond file stream length) with cfimage when reading remote files. My solution was to use cfhttp to read the image instead. I also updated the code to use a better named variable "resizedImgDestination".

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top