Reading/Loading an Image
When you think of digital images, you probably think of sampled image formats such as the JPEG image format used in digital photography, or GIF images commonly used on web pages. All programs that can use these images must first convert them from that external format into an internal format.
Java 2D supports loading these external image formats into its BufferedImage format using its Image I/O API which is in the javax.imageio package. Image I/O has built-in support for GIF, PNG, JPEG, BMP, and WBMP. Image I/O is also extensible so that developers or administrators can «plug-in» support for additional formats. For example, plug-ins for TIFF and JPEG 2000 are separately available.
To load an image from a specific file use the following code, which is from LoadImageApp.java :
BufferedImage img = null; try < img = ImageIO.read(new File("strawberry.jpg")); >catch (IOException e)
Image I/O recognises the contents of the file as a JPEG format image, and decodes it into a BufferedImage which can be directly used by Java 2D.
LoadImageApp.java shows how to display this image.
If the code is running in an applet, then its just as easy to obtain the image from the applet codebase. The following excerpt is from LoadImageApplet.java :
The getCodeBase method used in this example returns the URL of the directory containing this applet when the applet is deployed on a web server. If the applet is deployed locally, getCodeBase returns null and the applet will not run.
The following example shows how to use the getCodeBase method to load the strawberry.jpg file.
Note: If you don’t see the applet running, you need to install at least the Java SE Development Kit (JDK) 7 release.
LoadImageApplet.java contains the complete code for this example and this applet requires the strawberry.jpg image file.
In addition to reading from files or URLS, Image I/O can read from other sources, such as an InputStream. ImageIO.read() is the most straightforward convenience API for most applications, but the javax.imageio.ImageIO class provides many more static methods for more advanced usages of the Image I/O API. The collection of methods on this class represent just a subset of the rich set of APIs for discovering information about the images and for controlling the image decoding (reading) process.
We will explore some of the other capabilities of Image I/O later in the Writing/Saving an Image section.
Writing/Saving an Image
This lesson started with an explanation for using the javax.imageio package, to load images from an external image format into the internal BufferedImage format used by Java 2D. Then it explains how to use the Graphics.drawImage() to draw that image, with optional filtering.
The final stage is saving a BufferedImage object into an external image format. This may be an image that was originally loaded by the Image I/O class from an external image format and perhaps modified using the Java 2D APIs, or it may be one that was created by Java 2D.
The Image I/O class provides a simple way to save images in a variety of image formats in the following example:
static boolean ImageIO.write(RenderedImage im, String formatName, File output) throws IOException
The formatName parameter selects the image format in which to save the BufferedImage .
The ImageIO.write method calls the code that implements PNG writing a “PNG writer plug-in”. The term plug-in is used since Image I/O is extensible and can support a wide range of formats.
But the following standard image format plugins : JPEG, PNG, GIF, BMP and WBMP are always be present.
Each image format has its advantages and disadvantages:
Format | Plus | Minus |
---|---|---|
GIF | Supports animation, and transparent pixels | Supports only 256 colors and no translucency |
PNG | Better alternative than GIF or JPG for high colour lossless images, supports translucency | Doesn’t support animation |
JPG | Great for photographic images | Loss of compression, not good for text, screenshots, or any application where the original image must be preserved exactly |
For most applications it is sufficient to use one of these standard plugins. They have the advantage of being readily available. The Image I/O class provides a way to plug in support for additional formats which can be used, and many such plug-ins exist. If you are interested in what file formats are available to load or save in your system, you may use the getReaderFormatNames and getWriterFormatNames methods of the ImageIO class. These methods return an array of strings listing all of the formats supported in this JRE.
String writerNames[] = ImageIO.getWriterFormatNames();
The returned array of names will include any additional plug-ins that are installed and any of these names may be used as a format name to select an image writer. The following code example is a simple version of a complete image edit/touch up program which uses a revised version of the ImageDrawingApplet.java sample program which can be used as follows :
- An image is first loaded via Image I/O
- The user selects a filter from the drop down list and a new updated image is drawn
- The user selects a save format from the drop down list
- Next a file chooser appears and the user selects where to save the image
- The modified image can now be viewed by other desktop applications
The complete code of this example is represented in SaveImage.java .
In this lesson you have learned just the basics of Image I/O , which provides extensive support for writing images, including working directly with an ImageWriter plug-in to achieve finer control over the encoding process. ImageIO can write multiple images, image metadata, and determine quality vs. size tradeoffs. For more information see Java Image I/O API Guide.