In the Java track of Chapter
11 we focused on the java.awt.Image
class. The Image
class is fine for basic image tasks but it has limited capabilities.
With Java 1.2 and the Java2D classes, came the java.awt.image.BufferedImage,
which is a subclass of Image.
It provides a more open and structured internal design with much
greater access to the image data.
As shown in figure 11.1, a BufferedImage
includes a ColorModel
object and a Raster
object, which in turn contains instances of SampleModel
and Databuffer.
Figure Suppl.11.1 - The BufferedImage
class object holds
a ColorModel
object and a Raster
obejct, which in turn holds a
DataBuffer
and a SampleModel.
A color model refers to how to the data describes the colors as
they will appear in the display. A common type of color model is
RGB model in which each pixel is determined by the specified values
of Red, Green, and Blue. Java offers an aRGB model where an alpha
or transparency factor is included with the RGB values. One can
also have grey scale models and index models where a data value
holds an index into a palette of a fixed number of colors.
The raster refers to the data that specifies the colors of the
individual pixels. The Raster
instance is actually composed of the raw data in a Databuffer
and a SampleModel
that details how the raw data values get translated into the color
specifications for the model.
The term sample refers to one of the component values that
describes the pixel. For a RGB color model, for example, there are
three samples - the red sample, the green sample, and the blue sample
- that make up a pixel. The collection of values of a particular
sample for all the pixels is referred to as a band. That is, if
you filtered an image to show only the red values, this would be
the red band.
The bands could be assembled in several different ways. For example,
the band arrays could be assembled sequentially with the red array
first, green array second and blue array last. Or they could be
interleaved within a single array in triplets of samples for each
pixel. That is, the first three array element hold the red, green,
and blue samples, respectively, for the first pixel, and then repeats
for the full image. We will show later that Java by default packs
alpha and RGB samples for a pixel into a single 32 bit int value.
Loading
For BufferedImages
you can use the image
file loading techniques described in the Java track and then
convert (see below) the Image
object to a BufferedImage.
However, you can also use the static methods supplied with the javax.imageio.ImageIO
class. These include
public static BufferedImage read (File
input)
public static BufferedImage read (URL
input)
for GIF, PNG, and JPEG image files. You don't do image load monitoring
with these methods. If you believe that image loading from a URL
may cause a substantial delay, then you can do the reading in a
thread or load as an image with the MediaTracker
and then convert the Image to a BufferedImage
when its ready.
If there are other image types available with your implementation
you can use
String[] formatNames = ImageIO.getReaderFormatNames
();
to find the full list. This method returns names such as "gif",
"jpeg", and "png". (Java 1.5 will include "bmp".)
This method
formatNames = ImageIO.getReaderMIMETypes
();
returns strings in the form "image/jpeg" and "image/png"
for the available image formats.
Creating BufferedImages
The BufferedImage
class provides a constructor in which you pass the desired dimensions
and a parameter indicating the type of object.
BufferedImage bufImage =
new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);
g = bufImage.getGraphics();
paint(g);
The overridden getGraphics()
method for BufferedImage
returns a Graphics2D
object as its superclass Graphics
type.. An alternative is to use the CreateGraphics()
method that explicitly returns a Graphics2D
type.
The third parameter in the BufferedImage
constructor is the image format. In the above example, TYPE_INT_ARGB
indicated the transparency + RGB components packed as 8 bit values
in a 32 bit int value. TYPE_INT_RGB
would create a RGB image with no alpha transparency. TYPE_BYTE_GRAY
creates a gray scale image while TYPE_BYTE_BINARY
for 1, 2 and 4 bit scale image with an indexed color model. The
BufferedImage
class includes over a dozen image type constants.
The devices (monitors, PDA screens, printers) for display can vary
considerably in their resolution, color model, transparency, etc.
You can create a BufferedImage
with a GraphicsConfiguration
object that defines the characteristics of the target device where
a given graphics context (Graphics2D)
will render the image:
GraphicsEnvironment graphEnv =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice graphDev = ggraphEnv.getDefaultScreenDevice();
GraphicsConfiguration graphConfig = graphDev.getDefaultConfiguration();
// Can now create the image with
the GraphicsConfiguration
bimage = graphConfig.createCompatibleImage(width,
height, type);
Here type
= Transparency.OPAQUE, Transparency.OPAQUE,
or Transparency.TRANSLUCENT
You can also obtain the GraphicsConfiguration
from a given graphics context object - Graphics2D
as in
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
GraphicsConfiguration graphConfig = g2.getDefaultConfiguration();
and then you can create the BufferedImage
as shown above from the GraphicsConfiguration.
Image
to BufferedImage
The Java2D API offers many image tools and it works primarily with
the BufferedImage
class. You might encounter a situation where you obtain an Image
object but you want to apply Java 2D operations to the image. You
can obtain a BufferedImage
object from an Image
object by drawing the image onto the graphics context of the BufferedImage.
// Convert Image to BufferedImage
Graphics2D bufImageGraphics = bufferedImage.createGraphics();
bufImageGraphics.drawImage(image, 0, 0, null);
Another approach to creating images is to build them directly
from pixel arrays. We will discuss this approach in the image processing
sections later in this chapter.
References & Web Resources
Latest update: Dec. 3, 2004
|