Java Tip 32: You'll flip over Java images -- literally!

Avoid filtering when flipping, scaling, and cropping images -- with Java 1.1

Have you ever wanted to do simple image manipulations like flipping, scaling, and cropping, but didn't want to bother with image filters? Starting with Java 1.1, you can do this very easily with a new drawImage method. The method signature is as follows:

public boolean drawImage (Image img,
                          int dx1, int dy1, dx2, dy2,
                          int sx1, int sy1, sx2, sy2,
                         [Color backgroundColor,]
                          ImageObserver observer)

The Image, optional background color, Color, and ImageObserver parameters are shared with the Java 1.0 varieties of the method, along with the return value. However, new and different to Java 1.1 are the four sets of points. They describe source and destination bounding rectangles for the image. Starting with the 's' parameters, the coordinates describe the source piece of the original image to draw. If the (x1, y1) corner is (0, 0), and the (x2, y2) corner is (img.getWidth(this), img.getHeight(this)), then the entire image will be drawn. On the other hand, if the coordinates specify a smaller size, the image is cropped to the area specified. The source corners must be the top-left and bottom-right corners of the area to draw, as shown in Figure 1.

The following code in a Java 1.1 program demonstrates cropping to generate Figure 1.

g.drawImage (im,
             0, 0, 135, 90,
             65, 5, 200, 95,
             this);
Figure 1: Cropping the JavaWorld logo

Working with the 'd' parameters is where the real interesting things happen. These parameters describe the destination drawing area for the piece of the source image you selected. Since the points must be opposite corners of a rectangle, four options are available for these points:

  • Keeping the coordinates in the same corners
  • Swapping x-coordinates
  • Swapping y-coordinates
  • Swapping both coordinates

Keeping the coordinates in the same corners results in the scaling of the image. (No scaling will be done if the differences between the height and width of the two point sets is identical.) See Figure 2 below.

The following source will compress the width to half size and double the height:

g.drawImage (im,
             0, 0, im.getWidth(this)/2, im.getHeight(this)*2, 
             0, 0, im.getWidth(this), im.getHeight(this),
             this);
Figure 2: Scaled image to half width and twice height

Swapping x coordinates has the points in the top-right and bottom-left corners. This results in a flip along the vertical axis, as shown in Figure 3. Here's the code for implementing this flip.

g.drawImage (im, 
             im.getWidth(this), 0, 0, im.getHeight(this),
             0, 0, im.getWidth(this), im.getHeight(this),
             this);
Figure 3: Flipping the image along the vertical axis

Swapping y coordinates, as shown in Figure 4 and in the code below, has the points in the bottom-left and top-right corners. This results in a flip along the horizontal axis.

g.drawImage (im, 
             0, im.getHeight(this), im.getWidth(this), 0,
             0, 0, im.getWidth(this), im.getHeight(this),
             this);
Figure 4: Flipping the image along the horizontal axis

Finally, Figure 5 shows how swapping both coordinates results in a flip along both axis. The code is as follows:

g.drawImage (im, 
             0, im.getHeight(this), im.getWidth(this), 0,
             0, 0, im.getWidth(this), im.getHeight(this),
             this);
Figure 5: Flipping the image along the vertical and horizontal axes

That's all there is to the new drawImage in Java 1.1. If the image is transparent, you can provide a background color that will seep through. Otherwise, the optional parameter is ignored. Unfortunately, you cannot use drawImage to rotate the image. If you do want to rotate the image, you have to do more work and subclass ImageFilter, just like with Java 1.0.

Although not a Java drinker (he gets his caffeine fix from Coke), John Zukowski has been consulting for most of the past decade. After founding the Mid-Atlantic Java User Group (MAJUG), John relocated to Boston from Washington, D.C., and is now a Software Mage with MageLang Institute. He is the author of Java AWT Reference from O'Reilly & Associates and the Focus on Java guide at the Mining Company.

Learn more about this topic