Previous | Next | Trail Map | Creating a User Interface | Working with Graphics


Improving the Appearance and Performance of Image Animation

You might have noticed two things about the animation on the previous page: The problem of displaying partial images is easy to fix, using the MediaTracker class. The problem of slow image loading requires that you change the image format somehow; this page will give you some suggestions for doing so.

Using MediaTracker to Delay Image Display

The MediaTracker class makes it easy to find out when a group of images is fully loaded. Here's a modified version of the example applet that uses MediaTracker. This applet doesn't draw unless every image is fully loaded. (See the MediaTracker documentation(in the API reference documentation)for an example that draws the background immediately, but delays drawing the animated images.)

Here is the applet in action:


Your browser can't run 1.0 Java applets. If it could, you'd see Duke waving at you.

Below is the changed code, which uses a MediaTracker to help delay image display. Differences are marked in a bold font.

. . .//Where instance variables are declared:
MediaTracker tracker;

. . .//In the init() method:
tracker = new MediaTracker(this);
for (int i = 1; i <= 10; i++) {
    images[i-1] = getImage(getCodeBase(),
                           "../../../images/duke/T"+i+".gif");
    tracker.addImage(images[i-1], 0);
}
. . .

. . .//Near the end of the update() method:
// Paint only after all images have arrived.
if (tracker.statusID(0, true) == MediaTracker.COMPLETE) {
    offGraphics.drawImage(images[frameNumber % 10], 0, 0, this);
}
The new example isn't perfect. For one thing, it doesn't give any feedback to let the user know to wait. See [somewhere] for information on how to give feedback.

Speeding Up Image Loading

Whether or not you use MediaTracker, loading images using URLs (as applets generally do) generally takes a long time. Most of the time is taken up by initiating HTTP connections. Each image file requires a separate HTTP connection, and each connection can take several seconds to initiate. The key to avoiding this performance hit is to combine the images in a single file. You can further improve performance by using some sort of compression scheme, especially one that's designed for moving images.

One simple way to combine images in a single file is to create an image strip -- a file that contains several images in a row. Here's an example of an image strip:

jack.gif:

To draw an image from the strip, you first set the clipping area to the size of one image. Then you draw the image strip, shifted to the left (if necessary) so that only the image you want appears within the clipping area. For example:

// Images in the strip are numbered from 0 to 3;
// imageNumber is the number of the image we want to draw.
Dimension d = imageStrip.size();
int imageWidth = d.width / numImages;
g.clipRect(x, y, imageWidth, d.height);
g.drawImage(imageStrip, x - imageNumber*imageWidth, y, this);

If you want image loading to be faster still, you should look into image compression schemes, especially ones like Flic that perform inter-frame compression.


Previous | Next | Trail Map | Creating a User Interface | Working with Graphics