JAVA: RELATIONSHIP BETWEEN ANIMATED GIF AND IMAGE OBSERVER
BACKGROUND

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.

<<INDEX>>
(C) F. Permadi