The built in Image object in Java is very nice. One thing
you might not know already is that Java already support
animated-gif. There are times however, when things might not seem to work correctly. For example:
-
The gif only displays the first frame and never animates
-
The gif only animates when the
application/applet repaints.
-
You have a program that uses a dirty rectangle to
paint, and you don't know when to paint the next frame of the
animation.
To better understand how animated gif works, let's
see what happens when you use an animated gif.
When you call drawImage(Img image, int x, int
y, ImageObserver imageObserver) with an animated gif, one of the parameters is
an ImageObserver object. Often times, this
ImageObserver object is set to null or the current applet; and
quickly forgotten. This imageObserver is in fact very
important because it will be the one who receives notification
whenever the animated gif needs to paint the next frame. Consider
this example:
public class Applet1 extends Applet
{
private Image m_image=null;
public void init()
{
m_image=getImage(getDocumentBase(), "images/clock.gif");
}
public void paint(Graphics g)
{
g.drawImage(m_image,0,0,this);
}
public boolean imageUpdate( Image img, int flags, int x, int y,
int w, int h )
{
System.out.println("Image update: flags="+flags+
" x="+x+" y="+y+" w="+w+" h="+h);
repaint();
return true;
}
}
When this is run, here the console printout:
Image update: flags=3 x=0 y=0 w=110 h=110
Image update: flags=4 x=0 y=0 w=0 h=0
Image update: flags=8 x=0 y=0 w=108 h=1
Image update: flags=8 x=0 y=1 w=108 h=1
Image update: flags=8 x=0 y=2 w=108 h=1
Image update: flags=8 x=0 y=3 w=108 h=1
Image update: flags=8 x=0 y=4 w=108 h=1
Image update: flags=8 x=0 y=5 w=108 h=1
Image update: flags=8 x=0 y=6 w=108 h=1
Image update: flags=8 x=0 y=7 w=108 h=1
Image update: flags=8 x=0 y=8 w=108 h=1
Image update: flags=8 x=0 y=9 w=108 h=1
.......
Image update: flags=8 x=0 y=97 w=108 h=1
Image update: flags=8 x=0 y=98 w=108 h=1
Image update: flags=8 x=0 y=99 w=108 h=1
Image update: flags=8 x=0 y=100 w=108 h=1
Image update: flags=8 x=0 y=101 w=108 h=1
Image update: flags=8 x=0 y=102 w=108 h=1
Image update: flags=8 x=0 y=103 w=108 h=1
Image update: flags=8 x=0 y=104 w=108 h=1
Image update: flags=8 x=0 y=105 w=108 h=1
Image update: flags=8 x=0 y=106 w=108 h=1
Image update: flags=8 x=0 y=107 w=108 h=1
Image update: flags=16 x=0 y=0 w=110 h=110
Image update: flags=16 x=0 y=0 w=110 h=110
Image update: flags=16 x=0 y=0 w=110 h=110
Image update: flags=16 x=0 y=0 w=110 h=110
Image update: flags=16 x=0 y=0 w=110 h=110
Image update: flags=16 x=0 y=0 w=110 h=110
.......
The first call to paint registers the
applet (this) as the imageObserver. At this point, the image is
not fully loaded yet. As the loading progresses, imageUpdate()
is called. (I override the imageUpdate() function here; the
default one already calls repaint for you, that's why in most cases
you don't have to do anything).
-
The first call to the imageUpdate()
establishes the width and height of the image.
-
The second call to the imageUpdate()
establishes (flag=4).
-
Following those, we see that imageUpdate()
is called for every scanline of the image.
-
Once all the scanlines are loaded (green text), imageUpdate()
is called every time the frame changes (whenever the next frame of the
animated gif is ready to be drawn). Note that the interval will
follow the interval specified in the animated gif file, (unless
it takes longer to load the frame). If you look at the console
of the sample applet, you will see the imageUpdate() call
everytime the frame changes.