Java Institute DreamsCity 2000
Welcome to DreamsCity
Return to Java Institute

CREATING IMAGE THUMBNAILS

This tip demonstrates how you can create a small thumbnail version 
of a larger image. This is especially important for web applications
that need to display a number of images on a page and do it in
a reasonable amount of time.
The tip applies to the Java(tm) 2 Platform, JDK(tm) v1.2 and uses the com.sun.image.codec.jpeg package. Although this package is currently included in JDK v1.2, it's not yet part of the Java 2 Platform APIs and so it might change or be deleted in the future. The example program below illustrates how to create an image thumbnail. The program takes any GIF or JPEG file and creates a smaller JPEG file. The program shrinks the original image so that it fits into a square whose size you specify. In other words, the program maintains the aspect ratio, that is, the width-to-height ratio, of the original image. It also ensures that the width and height of the thumbnail are less than the size you specify. Here's the code for the example program. import java.awt.Image; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.io.FileOutputStream; import javax.swing.ImageIcon; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; class Thumbnail { public static void main(String[] args) { createThumbnail(args[0], args[1], Integer.parseInt(args[2])); } /** * Reads an image in a file and creates a thumbnail in another file. * @param orig The name of image file. * @param thumb The name of thumbnail file. Will be created if necessary. * @param maxDim The width and height of the thumbnail must * be maxDim pixels or less. */ public static void createThumbnail(String orig, String thumb, int maxDim) { try { // Get the image from a file. Image inImage = new ImageIcon(orig).getImage(); // Determine the scale. double scale = (double)maxDim/(double)inImage.getHeight(null); if (inImage.getWidth(null) > inImage.getHeight(null)) { scale = (double)maxDim/(double)inImage.getWidth(null); } // Determine size of new image. One of them // should equal maxDim. int scaledW = (int)(scale*inImage.getWidth(null)); int scaledH = (int)(scale*inImage.getHeight(null)); // Create an image buffer in which to paint on. BufferedImage outImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB); // Set the scale. AffineTransform tx = new AffineTransform(); // If the image is smaller than the desired image size, // don't bother scaling. if (scale < 1.0d) { tx.scale(scale, scale); } // Paint image. Graphics2D g2d = outImage.createGraphics(); g2d.drawImage(inImage, tx, null); g2d.dispose(); // JPEG-encode the image and write to file. OutputStream os = new FileOutputStream(thumb); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); encoder.encode(outImage); os.close(); } catch (IOException e) { e.printStackTrace(); } System.exit(0); } } You run the program like this: java Thumbnail <original.{gif,jpg}> <thumbnail.jpg> <maxdim> Notice that the program takes three parameters. The first parameter is the name of the file for the source image. The second parameter is the name of the file for the resulting image thumbnail. The third parameter specifies the maximum number of pixels for the width and height of the thumbnail. The width and height of the thumbnail will be no larger than the value of maxDim. The width or height of the thumbnail can be smaller than maxDim if the width or height of the original image is smaller. The program first loads the image file using the ImageIcon class. This class differs from Toolkit.getImage() in that ImageIcon doesn't return until the image is fully loaded. The image needs to be fully loaded in order to immediately access its width and height. With the width and height, the program can determine the scaling factor. This means how much the image needs to be reduced so that it can fit into a square of maxDim pixels. Both the width and height of the image are scaled down by the same amount to maintain the aspect ratio. The program scales the image. It creates a transform (AffineTransform) object to do the scaling and an image buffer to hold the new scaled image. Using the scale factor, the program can determine the exact size of the thumbnail image and the size of an image buffer just large enough to hold it. The transform is set with the scaling factor. However, no scaling takes place if the original image is smaller than the thumbnail. After scaling, the program paints the original image onto the new image buffer. It does this by creating a graphic context on the image buffer and then painting the original image using the graphics context. Now the thumbnail is in image buffer. The final step is to convert the image buffer into a JPEG stream to be written to a file. This is done using the JPEGImageEncoder.encode() method.

Any comments? email to:
richard@dreamscity.net