Wednesday, April 30, 2008

ColdFusion 8: Wrap and scale image text (Coming soon to a theatre near you)


Update November 16, 2009: Unfortunately, it looks like the RTF functionality is being moved to an incubator project:

http://www.mail-archive.com/itext-questions@lists.sourceforge.net/msg47892.html
http://www.mail-archive.com/itext-questions@lists.sourceforge.net/msg48015.html

So I took a hiatus from blogging for a while. Work has been a bit crazy. Seems like every time I think about blogging it is already time to stumble into bed, get some sleep and start the cycle all over again.

Anyway, in my scant spare time I have been batting around the idea of how to automatically scale wrapped text to fit a given area. It is still in the "rough" stages, but I have finally worked out a raw example that seems to be working .. so far. I say "so far" because those fonts are tricky devils. But I like a challenge. Now if only there were more hours in the day..

Since my brain has officially left the building for today, I will try and post the first draft code tomorrow or the day after. But for now here is a screen shot of the available options. Yes, the form is terribly bland but I was more interested in the image code behind it than creating a slick looking form ;-)

Later!


...Read More

Saturday, April 26, 2008

ColdFusion 8.0.1 Patch - Issue: Image files are locked after ImageResize

Recently an adobe forum member, that goes by the name hans blix, posted about a problem with deleting files that were manipulated with CF's image functions, under CF 8.0.1. The image files seemed to be locked and could not be deleted until ColdFusion was restarted.

In his case he was reading an image with <cfimage>, resizing it, then deleting the original file. Apparently, ImageResize() seemed to be locking the image file. So the call to delete the original image generated an exception:

ColdFusion could not delete the file <path to image file> for an unknown reason.


Fortunately, Ken Smith mentioned there is a patch for this issue. So if you are also encountering this problem, you can find the patch here: Patch for CFImage and Image functions in ColdFusion 8.0.1 (kb403411).


UPDATE: The image hotfix was updated on 08/15/2008. The file name is exactly the same as the one released on 05/07/2008. So check the file timestamp to make sure you have the latest fix.

...Read More

Sunday, April 6, 2008

OT: Go Wish!

So I went to submit a wish/bug report and I noticed the url had had changed. The current one is:

http://www.adobe.com/cfusion/mmform/index.cfm?name=wishform

Now I have to admit, I always got a kick out of the old one:
http://www.adobe.com/go/wish/

There was a silly part of my brain that got a little creative with that particular url:
Developer: I would like to request an enhancement.
Response: Yeah.. right (chuckle) . Go wish!

It also reminded me of a children's card game called go fish
Developer: Got any bugs?
Response: Go Fish!

Incredibly silly of me, I know. But I am really sorry they changed it. I will miss the chuckle I used to get every time I saw it ;)

...Read More

Saturday, April 5, 2008

ColdFusion 8 - ImageResize is Losing It

An adobe forum member, that goes by the nickname dbldutch, mentioned a problem they were having with ImageResize. In some cases the resized image is off by 1 pixel. To demonstrate, take the following example (by dbldutch). Create a test image that is 458 x 229. Then try and resize it to 100 x 50.


<cfscript>
img = ImageNew( "", 458, 229, "rgb", "##d8bfd8" );
ImageSetDrawingColor( img, "##000000" );
ImageSetAntialiasing( img, "on" );
attr = { font="Arial", size="24", style="bold" };
ImageDrawText( img, "Out of my mind. Back in five minutes", 15, 125, attr);
ImageResize( img, 100, 50 );
</cfscript>

<cfdump var="#ImageInfo( img )#" label="Resized ImageInfo">


If you view the dimensions of the new image, the width and height are 1 pixel smaller than they should be.



It appears to be a rounding problem. Christian Küpers mentioned having similar issues on Ben Nadel's blog. It is now listed as a Known Issue under the ColdFusion 8 Update 1 release notes.

ISSUE 70069:
Sometimes the ImageResize function produces an image 1 pixel shorter or narrower than the requested size. The image does resize properly if you specify bicubic, bilinear, nearest, or highestPerformance as the interpolation parameter value.



However, adding the recommended interpolation parameters does not always work. In the example below the final height is 63, instead of the requested height of 64. Though I think "highestPerformance" is the default anyway. So I was not really expecting it to work. Perhaps the addition of "highestPerformance" in the interpolation types is just a typo.



<cfscript>
img = ImageNew( "", 472, 243, "rgb", "##d8bfd8" );
ImageSetDrawingColor( img, "##000000" );
ImageSetAntialiasing( img, "on" );
attr = { font="Arial", size="24", style="bold" };
ImageDrawText( img, "Out of my mind. Back in five minutes", 15, 125, attr);
ImageResize( img, 114, 64, "highestQuality" );
</cfscript>

<cfdump var="#ImageInfo( img )#" label="Resized ImageInfo">


As you can see the resulting height is still 1 pixel short. The height = 63, instead of 64.



Since it appears to be a rounding problem, what may also work is incrementing the width and height with a small value like "0.0001". However, I have not done extensive testing. So I am uncertain if the math works out in every case.


<cfscript>
img = ImageNew( "", 472, 243, "rgb", "##d8bfd8" );
ImageSetDrawingColor( img, "##000000" );
ImageSetAntialiasing( img, "on" );
attr = { font="Arial", size="24", style="bold" };
ImageDrawText( img, "Out of my mind. Back in five minutes", 15, 125, attr);
ImageResize( img, 114.0001, 64.0001 );
</cfscript>

<cfdump var="#ImageInfo( img )#" label="Resized ImageInfo">


If anyone has any other alternatives, I would love to hear them.

...Read More

Friday, April 4, 2008

SOT: CF-Talk on houseoffusion.com rocks!

So I have been incredibly busy with a new project and have had zero time to blog. In my travels this week I ran into a weird problem with an old ColdFusion server. I had absolutely no clue about the cause, but CF-Talk on houseoffusion.com rode the rescue. A quick search of the archives turned up an excellent post that explained the problem and I had it fixed in minutes. So I just wanted to say "Thank You" to all of the knowledgeable people that regularly contribute on the CF-Talk list. You really saved my skin this week and you all rock!

...Read More

Determining which image formats are supported by your JVM

This entry is a mainly reminder to myself about image formats.

Before ColdFusion 8 introduced its built-in image functions, creating images took a bit more work. You normally had to tap into the underlying java classes to read and write images. One thing I always forget is how to determine which image formats are supported. Typically it is determined by the JVM version. To read or write a specific type of image (like GIF, PNG, TIFF, etcetera) an appropriate reader or writer must be registered with the JVM.

ColdFusion 8 ships with JVM 1.6. Out of the box, 1.6 is capable of reading and writing a lot of different image formats, such as GIF and TIFF. However, earlier versions of ColdFusion usually shipped with JVM 1.42. Unfortunately, version 1.42 is much more limited. For example, it can read GIF images but cannot write them. So it good to know which JVM you are using and which readers and writers are registered.


Addendum: Though ColdFusion 8 can write/create gif images, there is a known issue with creating transparent gif's from scratch. When the image is saved, transparent backgrounds are lost. The image is saved with a black background. I think this is a known issue with the underlying java image classes. However there is a work-around for this issue. See Creating Transparent GIF's with ColdFusion 8.


Display ColdFusion's JVM version

<cfset version = createObject("java", "java.lang.System").getProperty("java.version")>
<cfdump var="#version#">


Display image readers and writers registered with ColdFusion's JVM

<cfset ImageIO = createObject("java", "javax.imageio.ImageIO")>
<cfdump var="#ImageIO.getReaderFormatNames()#" label="ReaderFormatNames"><br>
<cfdump var="#ImageIO.getReaderMimeTypes()#" label="ReaderMimeTypes"><br>
<cfdump var="#ImageIO.getWriterFormatNames()#" label="WriterFormatNames"><br>
<cfdump var="#ImageIO.getWriterMIMETypes()#" label="WriterMIMETypes"><br>


The results should look something like the image below. The exact values displayed will vary depending on your JVM version. "FormatNames" are similiar to a file extension name, like "jpeg" or "gif". Consider them an informal way of referring to the MIME type when using certain methods of java's ImageIO class.



For those who have never used java to read/write images, here are a few simple examples. Bear in mind I am posting them for the curious. Since image functions are already built into ColdFusion 8, there is typically little need to use java directly. For MX6/7 there are several robust image handling options (that handle the java for you), such as Rick Root's ImageCFC. No need to reinvent the wheel ;)

Read an Image from a URL

<cfscript>
// construct the URL of the image to read
urlString = "http://www.google.com/press/images/logos/google_desktop_sm.jpg";
imageURL = createObject("java", "java.net.URL").init( urlString );
// read the image from the URL
ImageIO = createObject("java", "javax.imageio.ImageIO");
image = ImageIO.read( imageURL );
// write out the image bytes
byteStream = createObject("java", "java.io.ByteArrayOutputStream").init();
wasWritten = ImageIO.write( image, "jpeg", byteStream);
</cfscript>

<cfif wasWritten>
<!--- NOTE: The variable attribute requires MX7+ --->
<cfcontent type="image/jpeg" variable="#byteStream.toByteArray()#">
<cfelse>
Image format not supported
</cfif>


Read a Local Image File

<!--- read a local image file --->
<cfscript>
// construct a File object representing the image on disk
pathToImage = ExpandPath("sourceImageFile.jpg");
imageFile = createObject("java", "java.io.File").init( pathToImage );
// read the image from the File
ImageIO = createObject("java", "javax.imageio.ImageIO");
image = ImageIO.read( imageFile );
// write out the image bytes
byteStream = createObject("java", "java.io.ByteArrayOutputStream").init();
wasWritten = ImageIO.write( image, "jpeg", byteStream);
</cfscript>

<cfif wasWritten>
<!--- NOTE: The variable attribute requires MX7+ --->
<cfcontent type="image/jpeg" variable="#byteStream.toByteArray()#">
<cfelse>
Image format not supported
</cfif>


Read Image from a URL and Save it to a File

<cfscript>
saveToFile = ExpandPath("./name_of_saved_image.jpg");
// Construct the URL of the image to read
urlString = "http://www.google.com/press/images/logos/google_desktop_sm.jpg";
imageURL = createObject("java", "java.net.URL").init( urlString );
// Read the image from the URL
ImageIO = createObject("java", "javax.imageio.ImageIO");
image = ImageIO.read( imageURL );
// Save the image to a local file
outStream = createObject("java", "java.io.FileOutputStream").init( saveToFile );
wasWritten = ImageIO.write( image, "jpeg", outStream);
outStream.close();
</cfscript>

<cfif wasWritten>
<!--- display the local image --->
<cfoutput>
<img src="#saveToFile#">
</cfoutput>
<cfelse>
Image format not supported
</cfif>

...Read More

  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Header image adapted from atomicjeep