Resizing JPEG images: JAVA Vs .NET

    June 27, 2005

Joint Photographic Experts Group or JPEG for short is the most common image compression format today.

JPEG images are smaller then BMP images thanks to a data ordering algorithm. We are not going to deal with this algorithm in this article. We are going to look at images from a programmer’s point of view. Our end user needs to look at a scaled model of a large image, a thumbnail, if you will. How can we process our image in order to scale it down?

In this article we are going to examine two different ways of dealing with scaling JPEG images. JAVA using JAI (JAVA Advanced Imaging), and .NET using the class library and VB.NET.

Well first we have to start with the original image. In order to “break” it down to its raw format of pixels and colors we need to load the binary stream into an object we can deal with.

VB.NET: System.Drawing.Image

While in .NET we only get to keep the image data, JAI will also hold a number of additional parameters in addition to the image data.

Building our objects will look like this:

Dim objImage As System.Drawing.Image
objImage = System.Drawing.Image.FromFile("MyImage.jpg")
&nbsp&nbsp&nbsp&nbsp&nbsp InputStream is = new FileInputStream("MyImage.jpg");
&nbsp&nbsp&nbsp&nbsp&nbsp SeekableStream s = SeekableStream.wrapInputStream(is, true);
&nbsp&nbsp&nbsp&nbsp&nbsp RenderedOp objImage = JAI.create("stream", s);
&nbsp&nbsp&nbsp&nbsp&nbsp ((OpImage)objImage.getRendering()).setTileCache(null);
}catch(FileNotFoundException e){}

Both VB.NET and JAI are opening an input stream to the file and loading the data into the objImage.

Now let’s resize our image to a 100×100 thumbnail

Function ThumbnailCallback() AS Boolean
Return False
End Function

Dim objCallback AS System.Drawing.Image.GetThumbnailImageAbort = new System.Drawing.Image.GetThumbnailImageAbort(AddressOf ThumbnailCallback)

objImage = objImage.GetThumbnailImage(100, 100, objCallback, IntPtr.Zero)

float xScale = 100/objImage.getWidth();
float yScale = 100/objImage.getHeight();

ParameterBlock pb = new ParameterBlock();
&nbsp&nbsp&nbsp&nbsp&nbsp pb.addSource(objImage); &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp // The source image
&nbsp&nbsp&nbsp&nbsp&nbsp pb.add(xScale); &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp // The xScale
&nbsp&nbsp&nbsp&nbsp&nbsp pb.add(yScale); &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp // The yScale
&nbsp&nbsp&nbsp&nbsp&nbsp pb.add(0.0F); &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp // The x translation
&nbsp&nbsp&nbsp&nbsp&nbsp pb.add(0.0F); &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp // The y translation
&nbsp&nbsp&nbsp&nbsp&nbsp pb.add(new InterpolationNearest()); // The interpolation

objImage = JAI.create("scale", pb, null);

In VB.NET we need to provide a callback method for determining when the GetThumbnailImage method should prematurely cancel execution. GetThumbnailImageAbort is using a delegate. In GDI+ version 1.0, the delegate is not used; however, you must create a delegate and pass a reference to that delegate.

JAI uses a ParameterBlock to hold all the data it needs to process the image. It then uses its core class JAI to create a scale operation.

As we have seen in this article, both .NET and JAVA use the same technique to process images. Loading them into objects and then processing the data, but, while .NET’s Image object is limited in storing additional data and provides limited built in processing methods, JAVA’s RenderedOp is an object designed as a data class only and any processing must be done with the JAI core API.

*JAI is a heavy gun deigned for more complex image processing operations and another way to achieve image scaling can be done with the Package java.awt.image.


Mr. Gal Ratner graduated from the Technion Institute in Israel and has been writing software for over 10 years. He is the founder and CEO of Inverted Software located in southern California, which consults to large organizations.