Image I/O is a powerful API for reading
and writing images in an extensible variety of formats. Because
this power comes with a degree of complexity that can overwhelm
developers new to Image I/O (and possibly frustrate experienced
developers), this article presents a grab bag of useful Image I/O
utilities that can make your Image I/O experiences more productive.
Help yourself to them.

These utilities are implemented by theca.mb.javajeff.iioutil package'sIIOUtilities class and its static methods, and by theUnsupportedFormatException support class. After
introducing these methods, and three example applications that
demonstrate their usefulness, I use Apache Ant to build and package
these classes into an iioutil.jar JAR file, and build
these applications.

Note: I built and tested this article's code with Sun's
J2SE 5.0 SDK and Apache Ant 1.6.5. Windows 98 SE was the underlying
platform.

Create Image Viewer Accessory for File Chooser

A javax.swing.JFileChooser instance can be
customized through an accessory (ajavax.swing.JComponent subclass instance) to view
images, to present additional dialog box controls, or to do
something else. After creating the accessory, this component is
attached to the file chooser by invokingJFileChooser's

method. This method creates and returns an image
viewer accessory for the specified file chooser, having the
specified dimensions. No exceptions are thrown.

I've created an Example1 application that demonstratescreateImageViewerAccessory(). This application creates
and displays a single open file chooser with the image viewer
accessory. When the user highlights a file whose filename suffix
matches one of Image I/O's supported suffixes, the image is
rendered on the image viewer's drawing area. Check out Figure
1.

Figure 1. The image viewer centers small images on its drawing
area

This application's

public static void main(String []args)

method first creates a JFileChooser that
references the current directory. This method next invokescreateImageViewerAccessory() to create the accessory,
followed by setAccessory() to attach the accessory to
the file chooser. This open file chooser is then shown (with no
parent component):

The createImageViewerAccessory() method creates the
accessory as an instance of its IV (Image Viewer)
local class. This method passes its arguments to IV's
constructor, and then returns the resulting component. The
following IIOUtilities excerpt presents and explains
the workings of createImageViewerAccessory() and itsIV class:

Capture Screen Contents to File

The java.awt.Robot class provides a

publicBufferedImage createScreenCapture(Rectangle screenRect)

method for capturing screen contents (without the mouse cursor) to
a java.awt.image.BufferedImage. Because it is
convenient to capture screen contents and save these contents to a
file in one step, IIOUtilities provides the following
two methods:

public static void captureScreenToFile(Stringfilename)

captures the entire screen's contents to the file
identified by filename. The filename's
suffix determines the format in which the contents are saved--jpg identifies the JPEG format, for example.

This method throws java.awt.AWTException (screen
cannot be captured), java.io.IOException (capture
cannot be saved to a file), orUnsupportedFormatException (filename's
suffix is not recognized by Image I/O).

is similar to the previous method, except
that a subset of the screen (as determined by thebounds parameter's screen coordinates) is saved.

In addition to the previous method's exceptions, thiscaptureScreenToFile() method throws anIllegalArgumentException if any boundary value is
negative, or if the capture area exceeds the screen's
dimensions.

I've created an Example2 application that demonstrates
both captureScreenToFile() methods. This application's
GUI, which is shown in Figure 2, presents two buttons for capturing
the GUI's frame window and the entire screen. The frame window is
captured to window.jpg, and the entire screen is
captured to screen.jpg.

Figure 2. The button stays pressed during the capture, which
occurs in the button's action listener

The "Capture frame window" button's action listener first
determines the frame window's boundaries (for its width and height)
and upper-left-corner screen location. After merging these values
into a single java.awt.Rectangle, this rectangle andwindow.jpg are passed to the secondcaptureScreenToFile() method, which captures the
window to this file:

The "Capture entire screen" button's action listener is similar.
Rather than examine this listener, let's take a look at thecaptureScreenToFile(Rectangle bounds, String filename)
method, to see how it works.:

saves the contents of theBufferedImage to the file identified byfilename. An IOException is thrown if the
image cannot be saved; an UnsupportedFormatException
is thrown if Image I/O does not support filename's
suffix.

public static BufferedImage loadImageFromFile(Stringfilename)

loads an image from the file identified byfilename into a new BufferedImage. AnIOException is thrown if the image cannot be loaded;
an UnsupportedFormatException is thrown if Image I/O
does not support filename's suffix.

I've created an Example3 application that uses these
methods for image conversion. Example3 takes two command-line
arguments: the first argument identifies the source image's path
and name, and the second argument identifies the destination image's
path and name. The conversion is performed by

The saveImageToFile() method treats JPEG
destinations in a special way: this method establishes a 95-percent
compression quality so that the image is saved with low compression
(and will look good when reloaded). If you prefer to dynamically
specify compression quality, replace the hardcoded0.95f value in this method's source code (shown below)
with a private static field and suitable accessor methods:

Build the Image I/O Utilities JAR file and Example Applications

Now that we have explored the methods belonging to theIIOUtilities class, let's build this class and itsUnsupportedFormatException support class, and package
them into iioutil.jar--and also build the example
applications. We will use Apache Ant with build.xml to
automate these tasks. This script assumes the following directory
structure:

Before using Apache Ant, this tool's bin directory must
be added to the PATH environment variable. Also, theJAVA_HOME environment variable must refer to Java SE
5's home directory. I accomplish both tasks on my Windows platform
with the following setup.bat file--you might want to use
something similar on your platform.

After making sure that the directory containing src, the
batch file, and the XML script file is current, type ant (by
itself) to build iioutil.jar and the example applications.
Ant creates a bin directory that stores the JAR file and anexamples subdirectory with application classfiles. This tool
uses the following build.xml file for these builds.

Along with the default buildall task,build.xml reveals tasks for conveniently building the JAR
file itself (ant buildjar), and building the examples
without the JAR (ant buildex)--the JAR file must exist
before building the examples. We can also generate Javadoc
documentation (ant gendoc), and delete the binary and
documentation directories (ant cleanup).

Let's run the example applications. At the command line, change
to the Ant-created bin\examples directory. Specify thejava command with the -cp or-classpath options to add iioutil.jar to the
classpath, and specify an application classname. For example, specifyjava -cp ../iioutil.jar;. Example2 to run the Example2
application.

Conclusion

Want more Image I/O utilities? Chet Haase's "ImageIO: Just another example of better living by
doing it yourself" blog entry presents an ImageScaler
application for creating scaled JPEG images. Consider migrating
this application into a version of IIOUtilities.saveImageToFile() that scales an image to
a desired size, and then saves the scaled image.