Ok, so it’s not really in ColdFusion, but I wrong a Java library so that I could access image manipulation routines in my ColdFusion apps. Using the Java Advanced Imaging (JAI) API made it very easy to write a library to perform a variety of functions.
The Java 1.5 JDK must be installed on your system and used to compile this code (or to use the library I provide). By default ColdFusion 6 and 7 support up to 1.4 JDK, so this is an unsupported bit of code.
You can visit the Java Advanced Imaging Project page to download the binary for your OS of choice. By default the installation will place the files in your existing JDK or JRE location (for example, on Windows it will be something similar to C:\Program Files\Java\jre1.5.0_05), but you can override this and have the files installed directly into the LIB directory of your application server – for example – C:\jboss-4.0.4\server\default\lib.
Now we can start using those libraries to build a Java class, which you can use in ColdFusion. This is my simple class which you can use as a reference. I put in my notes and added links to the JAI specs page for specific operations.
package orbwave.ImageController;
/*
* Import the JAI libraries and the IO libraries to read, manipulate and save
* an image file.
*/
import java.io.*;
import java.awt.image.renderable.*;
import javax.media.jai.*;
import com.sun.media.jai.codec.*;
public class Controller {
// Private member variable to hold the original iamge file
private RenderedOp sourceFile = null;
/*
* Load a source image into a FileSeekableStream object for manipulation
*/
public void load(String file) throws IOException
{
FileSeekableStream fss = new FileSeekableStream(file);
sourceFile = JAI.create("stream", fss);
}
/*
* Save the manipulated image to the specified file location, with the
* specified type. Set the sourceFile reference back to null to prevent
* the file from being locked by this process
*/
public void save(String file, String type) throws IOException
{
FileOutputStream os = new FileOutputStream(file);
JAI.create("encode", sourceFile, os, type, null);
sourceFile = null;
os = null;
}
/*
* For cropping, I provide a simple 'centering' crop where the starting edges
* and the max edges are all equal
*
* Documentation:
* http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/CropDescriptor.html
*/
public void crop(float edge)
{
ParameterBlock params = new ParameterBlock();
params.addSource(sourceFile);
params.add(edge);
params.add(edge);
params.add((float) sourceFile.getWidth() - edge);
params.add((float) sourceFile.getHeight() - edge);
sourceFile = JAI.create("crop", params);
}
/*
* This scale method does an incremental process of scaling until the desired width
* is achieved. This process provides a MUCH smoother final image than a direct scale from
* the original size.
*
* Documenation:
* http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ScaleDescriptor.html
*/
public void scaleWidth(float width)
{
ParameterBlock params;
while (width < sourceFile.getWidth()) {
float esc = Math.max(((float) (width) / sourceFile.getWidth()),0.5f);
params = new ParameterBlock();
params.addSource(sourceFile);
params.add(esc).add(esc).add(0.0F).add(0.0F);
params.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC));
sourceFile = JAI.create("scale", params);
}
}
/*
* This scale method does an incremental process of scaling until the desired height
* is achieved. This process provides a MUCH smoother final image than a direct scale from
* the original size.
*
* Documenation:
* http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ScaleDescriptor.html
*/
public void scaleHeight(float height)
{
ParameterBlock params;
while (height < sourceFile.getHeight()) {
float esc = Math.max(((float) (height) / sourceFile.getHeight()),0.5f);
params = new ParameterBlock();
params.addSource(sourceFile);
params.add(esc).add(esc).add(0.0F).add(0.0F);
params.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC));
sourceFile = JAI.create("scale", params);
}
}
/*
* This operation rotates an image about a given point by a given angle, specified
* in degrees. The origin defaults to (0, 0).
*
* Documentation:
* http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/RotateDescriptor.html
*/
public void rotate(float degrees)
{
ParameterBlock params = new ParameterBlock();
params.addSource(sourceFile);
params.add((float)sourceFile.getWidth() / 2);
params.add((float)sourceFile.getHeight() / 2);
params.add(degrees);
params.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2));//interpolation method
sourceFile = JAI.create("rotate", params);
}
/*
* To create a thumbnail, I simply accept the maximum edge length wanted for the entire image
* and then compare with the width and height to determine which aspect should be used for
* resizing.
*
* Documenation:
* Refer to scaleHeight() or scaleWidth() methods for scale documentation
*/
public void createThumbnail(float edgeLength)
{
boolean useHeight = (sourceFile.getHeight() > sourceFile.getWidth());
while ( edgeLength < ((useHeight) ? sourceFile.getHeight() : sourceFile.getWidth()) ) {
float esc = Math.max(((float) (edgeLength) / ((useHeight) ? sourceFile.getHeight() : sourceFile.getWidth()) ),0.5f);
ParameterBlock params = new ParameterBlock();
params.addSource(sourceFile);
params.add(esc);
params.add(esc);
params.add(0.0F);
params.add(0.0F);
params.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2));//interpolation method
sourceFile = JAI.create("scale", params);
}
}
}
You can download the compiled library and place it in your WEB-INF\lib directory for your application.

After you’ve compiled your library, or downloaded my sample, you should restart your application server. Once it has restarted, you can start using the manipulation code in ColdFusion. Here’s some sample code.
<cfscript>
// Create an instance of the image editor
img = createobject("java", "orbwave.ImageController.Controller");
// Load a source file, scale to width to 320 pixels and save it
img.load('C:\\jboss-4.0.4\\server\\default\\deploy\\brownlees.war\\img\\DSC00121.JPG');
img.scalewidth(320);
img.save('C:\\jboss-4.0.4\\server\\default\\deploy\\brownlees.war\\img\\DSC00121_scaled.JPG','jpeg');
// Load a source file, scale to height to 320 pixels, rotate by 90 degrees and save it
img.load('C:\\jboss-4.0.4\\server\\default\\deploy\\brownlees.war\\img\\DSC00121.JPG');
img.scaleheight(320);
img.rotate(45);
img.save('C:\\jboss-4.0.4\\server\\default\\deploy\\brownlees.war\\img\\DSC00121_sclaed_rotated.JPG','jpeg');
</cfscript>
6 Responses for "Image manipulation in ColdFusion"
Hi,
I am trying to implement this but get the following error:
orbwave/ImageController/Controller (Unsupported major.minor version 49.0)
Am I doing something wrong?
Im running coldfusion 7 if that helps?
Would really love to see this one in action, looks like a great piece of kit!
Thanks,
Martin
Martin, you need the 1.5 JDK to compile this code as it requires some libraries that aren’t available in 1.4. I failed to mention that in my post and just added a Requirements section for future readers.
Ok many thanks for the reply. Bummer tho – was looking forward to messing about with this one!
Cheers for sharing the good work :-)
Hi Jim. Photos i received. Thanks
Hi Steve. Your link to orbwave.jar is broken.
Hi Steve,
I really like this article!
Unfortunally the scaleWidth() leads to java.lang.OutOfMemoryError: Java heap space when used on large images (> 1.3 MB). Is this a memory leak because of the loop?
Any suggestions would be welcome.
Leave a reply