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.
|