Working with Images in Java 1.1
Java provides some facilities to manipulate images. These are
contained in the java.awt.Image class and in the java.awt.image
package. These classes are VERY confusing. In this text, we try to
present some of the main features in an easy to understand way.
******************************************************
******************************************************
Opening an Image
Java has some very neat methods to read an image from
the disk from an url:
//opening an image from a file, String filename
Image my_image = Toolkit.getDefaultToolkit().getImage(filename);
//opening an image from the Internet, URL url
Image my_image = Toolkit.getDefaultToolkit().getImage(url);
******************************************************
******************************************************
The java.awt.Image class
This is object where Java stores an image. It is very easy to display
this image on the screen:
Graphics g = my_frame.getGraphics();
g.drawImage(my_image,x,y,my_frame);
In the same way, the image can be printed (g would be a printer page,
see Printing in Java).
You can get a larger or smaller copy:
Image scaled_image =
my_image.getScaledInstance(new_width,new_height,scalling_algorithm)
where scalling_algorithm is one of the algorithms defined in the
java.awt.Image class.
If you want to draw on your image, you can get a graphics object
and do anything:
Graphics g = my_image.getGraphics();
g.setFont(new Font("Dialog",Font.BOLD,20));
g.setColor(Color.red);
g.drawString("This is a cool picture",100,100);
When you want to know the image size the problems start. Basically,
there are the obvious methods:
int width = my_image.getWidth(image_observer);
int height = my_image.getHeight(image_observer);
image_observer can be set to null or to a Container (usually
the one where the image is drawn).
Java was designed to load the image while the program is running.
Thus, you may call these methods before Java knows the image
size. In this case, the image size will be set to -1. This is
a major problem for most programs that need to know the image size.
The way around this is to make your program wait until the image is
loaded (see Waiting for Image to be Loaded).
******************************************************
******************************************************
Waiting for Image to be Loaded
Java was designed to load the image while the program is running.
Thus, you may have problems calling any method that needs accesses
the image data if the image has not been loaded.
Therefore, after you open an image, create a scaled instance or
create an image from an array and before you get its size, grab its
pixels, call a filter on it, you should make your program wait
for the image to be loaded. This code
should work for most cases:
// create a media tracker to track the loading of
// my_image. my_component cannot be null, set it
// to the component where you will draw the image
// or to the main Frame in your application
MediaTracker media_tracker = new MediaTracker(my_component);
// add your image to the tracker with an arbitrary id
int id = 0;
media_tracker.addImage(my_image,id);
// try to wait for image to be loaded
// catch if loading was interrupted
try
{
media_tracker.waitForID(id);
}
catch(InterruptedException e)
{
System.out.println("Image loading interrupted : " + e);
}
******************************************************
******************************************************
Obtaining an Array of Image Pixels
For many real image processing tasks, it is necessary to
obtain an array with the image pixels. The code bellow
allow you to do this (ATTENTION: in this code we assume that
the image has been fully loaded, see Waiting for Image
to Load) :
//get image dimension
int w = ti.projected_image.getWidth(null);
int h = ti.projected_image.getHeight(null);
// the rectangle (x,y) to (x+w,y+h) will be grabbed
int x=0, y=0;
// offset into the array of the top left corner of the grabbed
// rectagle
int off = 0;
// horizontal size of the array
int scansize = w;
// pixels[] MUST BE ALLOCATED
int[] pixels = new int[h*w]; // allocate a larger array if offset is not
zero
// create a pixel grabber object
// pixels are stored in the default RGB color model
PixelGrabber pixel_grabber = new PixelGrabber(my_image, x, y, w, h,
pixels, off, scansize);
// grab pixels
try{
pixel_grabber.grabPixels();
}catch(InterruptedException e)
{
System.out.println("Couldn't grab pixels " + e);
}
The pixels will be stored in the pixels[] array in the default
RGB color model, use ColorModel.getRGBdefault() to get an
instance of this color model. The image can be processed in any
desired way, for example:
// code to turn image into a pink image :-)
int pink = Color.pink.getRGB();
for(int j=0;j= this.min_red)? red : 0;
green = (gren >= this.min_green)? green : 0;
blue = (blue >= this.min_blue)? blue : 0;
alpha = alpha << 24;
red = red << 16;
green = green << 8;
return alpha | red | green | blue;
}
}// end of class ThresholdImageFilter