Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Java™ Advanced Imaging (JAI) Examples
Report NDT4-08-2006
17 August 2006
Copyright © 2006 by NanoDotTek™
Permission is granted to reproduce this report provided that appropriate credit is given to
NanoDotTek™ as its author. However, this document is not to be reproduced for sale or
profit.
Disclaimer: Best effort has been made in the preparation of this report. However,
NanoDotTek™ makes no representations or warranties with respect to the accuracy or
completeness of the contents of this report, and specifically disclaims any implied
warranties of merchantability or fitness for any purpose. NanoDotTek™ shall not be
liable for any loss of profit or any other commercial damages, including but not limited to
special, incidental, consequential, or other damages.
1. Introduction
In general, the Java™ programming language is powerful partly because it readily
supports library construction and usage. An example of a powerful freeware library is
Java™ Advanced Imaging (JAI) for digital image processing, and this is available for
downloading from Sun Microsystems, Inc. However, the package is not really that easy
to use. Information such as the JAI pdf manual of 1999 [1] is available, but is now rather
old, and it did not have too many complete examples to begin with. Example source
codes can be found too (e.g., [2]), and these are certainly very helpful, but information
resources still tend to be somewhat “scattered,” and beginners will therefore likely find
integrating the “bits and pieces” together a hard task to accomplish.
Therefore, this report presents two very complete examples of JAI usage for reading
images in from files, displaying images to the terminal, and saving image files. This
report therefore represents a contribution to disseminating information about JAI (albeit a
minor contribution). The examples show how to split a color image into its constituent
color bands, and how to take what in principle may be an “arbitrary” two-dimensional
integer array, and save it to a file as an image. Actual pictures of the inputs, and
processed outputs are also provided.
2. Example 1
Our first example is based around the following source code (AccessRGB.java):
import java.awt.Frame;
import java.awt.image.renderable.ParameterBlock;
import java.awt.image.*;
import java.awt.image.Raster;
import java.awt.image.DataBuffer;
import java.awt.image.SampleModel;
import javax.media.jai.*;
import javax.media.jai.widget.*;
/**
* NOTE: 1) This routine compiles with deprecation warnings
*
relating to AWT constructs (which is not serious).
*
2) The idea is to experiment with accessing image spectral bands.
*
3) All three color bands of an input jpeg are extracted, and
*
saved to files as grayscale images. The red band is
*
scaled up, and displayed to the terminal as grayscale.
*
4) At least in principle, the user can choose a jpeg as
*
he/she sees fit just by changing the input filename string.
*
* NanoDotTek, 17 August 2006
*/
public class AccessRGB
{
public static void main(String[] args)
{
// Read image from a file ...
String fileName = "TestJpeg.JPG"; // Desired source file
// Read the file in as a PlanarImage ...
PlanarImage image1 = JAI.create("fileload",fileName);
// Extract some very basic information about image1 ...
int width1 = image1.getWidth();
int height1 = image1.getHeight();
int numBands1 = image1.getSampleModel().getNumBands();
// Verify the number of spectral bands in image1 ...
System.out.println(" Number of input image bands = " + numBands1);
// Assuming pixel (x,y) actually exists we now
// sample the image to get that particular pixel's value ...
int x = 50, y = 200; // pixel (x,y) (column x, row y)
// Get a Raster version of image1 ...
Raster image1Data = image1.getData();
// Extract pixel band information ...
int pixelR = image1Data.getSample(x,y,0);
int pixelG = image1Data.getSample(x,y,1);
int pixelB = image1Data.getSample(x,y,2);
// Output what has been found to the terminal ...
System.out.println(" Pixel (x,y) = (" + x + "," + y + ") has ... ");
System.out.println(" Red level = " + pixelR);
System.out.println(" Green level = " + pixelG);
System.out.println(" Blue level = " + pixelB);
// The coding that follows is derived from p. 186 of the
// manual jai1_0_1_guide.pdf, and uses bandSelect to
// extract the spectral bands of image1 ...
int[] bandIndicesR = new int[1];
int[] bandIndicesG = new int[1];
int[] bandIndicesB = new int[1];
bandIndicesR[0] = 0; // choose the red band
bandIndicesG[0] = 1; // choose the green band
bandIndicesB[0] = 2; // choose the blue band
// Stores the required input source, and parameters in a
// ParameterBlock (one for each color band) ...
ParameterBlock paramsR = new ParameterBlock();
paramsR.addSource(image1);
paramsR.add(bandIndicesR);
ParameterBlock paramsG = new ParameterBlock();
paramsG.addSource(image1);
paramsG.add(bandIndicesG);
ParameterBlock paramsB = new ParameterBlock();
paramsB.addSource(image1);
paramsB.add(bandIndicesB);
// Create RenderedImage versions of the spectral bands ...
RenderedImage imageR =
(RenderedImage)JAI.create("bandSelect", paramsR);
RenderedImage imageG =
(RenderedImage)JAI.create("bandSelect", paramsG);
RenderedImage imageB =
(RenderedImage)JAI.create("bandSelect", paramsB);
// Save all of the spectral band images to files ...
JAI.create("filestore",imageR,"redBand.JPG");
JAI.create("filestore",imageG,"greenBand.JPG");
JAI.create("filestore",imageB,"blueBand.JPG");
// Scale imageR (image of the red band) ...
ParameterBlock params = new ParameterBlock();
params.addSource(imageR);
params.add(1.25F);
params.add(1.25F);
PlanarImage redBand = JAI.create("scale",params);
// Get the width and height of redBand ...
int widthR = redBand.getWidth();
int heightR = redBand.getHeight();
// Attach redBand to a scrolling panel to be displayed ...
ScrollingImagePanel panel =
new ScrollingImagePanel(redBand,widthR,heightR);
// Create a frame to contain the panel ...
Frame window = new Frame("Red Band As Grayscale");
window.add(panel);
window.pack();
window.show();
}
}
The code above first reads in the jpeg source file TestJpeg.JPG (see Fig. 1 below
which displays the color image in this file). The image is initially read in as a
PlanarImage object. Certain JAI methods allow one to extract basic information about the
image such as its size, and a confirmation that the number of spectral bands is indeed
three. A Raster version (image1Data) of the input image is obtained making it easy to
access individual pixels. The code “samples” a pixel (chosen rather arbitrarily here) from
the image, and then outputs to the terminal the values of each spectral component for that
pixel. The “high level” bandSelect operation is employed to extract each color band
array. This involves creating suitable ParameterBlock objects, one for each band. These
tell the method JAI.create how to process the input image. The result is three
RenderedImage objects (called imageR, imageG, and imageB) again one for every color
band, and this type of image representation is a rather “high level” way to represent
images using JAI. The three color bands (monochrome images) are saved as grayscale
images to jpeg files. The red band is displayed to the terminal as a grayscale image using
Java abstract window toolkit (AWT) methods (versions that are now deprecated). The
image is also scaled up in size to illustrate how image scaling may be used.
Figure 1: The original photo was taken using a Minolta DiMAGE E323 camera
using settings AWB, AUTO, 2048, FINE. MS Paint was used to produce the
caption in the photo. The picture above is a cropped version of the original,
where the cropping was done using the software that came with the camera.
The color scheme in the original image of Fig. 1 will aid in interpreting the images to
follow which are grayscale depictions of the individual R (red), G (green), and B (blue)
color spectral bands that make up the original. The red, green, and blue color band
images appear in Figs. 2 to 4, respectively (see below).
Now we recall some basic ideas about digital imaging. For the image coding
schemes employed here each pixel’s spectral component is an integer taking on a value
from 0 to 255 (the range of values for a byte that represents an unsigned integer). Level 0
represents black, while level 255 is white. The higher the level the more energy at that
wavelength, and location in the image.
Figure 2: The red band component (256 gray levels) of the image in Fig. 1.
Observe in both Fig. 2 and Fig. 3 that the flowers appear rather bright. From the CIE
Chromaticity Diagram (which is readily available; see [3] or [4] for example) we now
recall that the color yellow is an additive combination of red and green, but not blue.
Hence we expect that the flowers should appear bright in the red and green spectral
bands. Since blue is not a constituent of yellow we expect that the flowers will appear
dark in the blue spectral band. This is certainly the case as may be seen in Fig. 4. The
table cloth is white, and we see that it appears bright in all bands. From the CIE chart we
recall that white is a more-or-less equal additive combination of the three primary colors.
In other words, the images seen in Figs. 2 to 4 all “make sense” given how they were
created.
Figure 3: The green band component (256 gray levels) of the image in Fig. 2.
Figure 4: The blue band component (256 gray levels) of the image in Fig. 1.
3. Example 2
The next (and last) sample Java code is:
import java.awt.Frame;
import java.awt.image.renderable.ParameterBlock;
import java.awt.image.*;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.DataBuffer;
import java.awt.image.SampleModel;
import javax.imageio.ImageIO;
import java.awt.Point;
import java.io.File;
import java.io.IOException;
import javax.media.jai.*;
import javax.media.jai.widget.*;
/**
* NOTE: 1) This routine takes the red band integer array from
*
an input jpeg file, and then converts the array to
*
a grayscale image that is saved to a file via ImageIO.
*
2) The code below is based on suggestions from B. Burkhalter,
*
and R. Santos (see GrayScaleImageNoJAI.java at
*
jaistuff.dev.java.net). Their input is much appreciated.
*
* NanoDotTek, 17 August 2006
*/
public class IntArrayToGrayscale
{
public static void main(String[] args) throws IOException
{
// The desired source file is ...
String fileName = "TestJpeg.JPG";
// Read in the file as a PlanarImage ...
PlanarImage image1 = JAI.create("fileload",fileName);
// Obtain a Raster version of the image ...
Raster image1Raster = image1.getData();
// We need the size of the input image ...
int width1 = image1Raster.getWidth();
int height1 = image1Raster.getHeight();
int numPixels = width1 * height1;
// Now extract the red band data from image1 ...
int redPart[] = new int[numPixels];
int entry = 0;
for (int h = 0; h < height1; h++)
for (int w = 0; w < width1; w++)
redPart[entry++] = image1Raster.getSample(w,h,0);
// Observe how image1Raster is 'raster scanned,' i.e.,
// data is read beginning at the upper left corner of the
// image, and going from left to right, and from top to bottom.
// Observe also that redPart is a 1D int array.
// Set things up for saving the redPart array to an output
// file as a grayscale image ...
BufferedImage redBufferedImage =
new BufferedImage(width1,height1,BufferedImage.TYPE_BYTE_GRAY);
WritableRaster redRaster = redBufferedImage.getRaster();
redRaster.setPixels(0,0,width1,height1,redPart);
// Apparently, png format is preferred for integer inputs ...
ImageIO.write(redBufferedImage,"PNG",new File("RedBandOut.png"));
}
}
The code above operates upon the same input image as Example 1 in the previous
section. However, it merely extracts the integer array corresponding to the red part of the
image’s spectrum, and saves it as a grayscale image in a png file. The operations
illustrated here are at a “lower level” compared to the code of the previous example. If
the reader runs the two codes of this report, displays images to the terminal, and visually
compares image RedBandOut.png to the jpeg image of Fig. 2 the reader will see that they
appear identical, as we would of course expect.
In principle, the integer array in IntArrayToGrayscale.java (above) could have come
from anywhere. One might use a suitably modified version of this code to do false color
imaging, for example.
Acknowledgment
B. Burkhalter (Sun Microsystems, Inc.) and R. Santos (see CreateGrayImageNoJAI.java
at jaistuff.dev.java.net) gave very useful assistance in creating the code of Example 2.
Their help is much appreciated. The Java code of this report was run under the BlueJ IDE
(version 2.1.0) using Java J2SE. The JAI version employed here is jai_1_1_2_01.
References
1. Programming in Java™ Advanced Imaging, Release 1.0.1, November 1999, Sun
Microsystems, Inc.
2. https://jaistuff.dev.java.net/
3. R. C. Gonzalez, P. Wintz, Digital Image Processing, Addison-Wesley Publishing
Co., 1977.
4. http://www.yorku.ca/eye/ciediag1.htm