Gif animation pauses at wrong frame / library: gifAnimation

edited October 2014 in Library Questions

Hello dear forum, I'm relatively new to Processing and I am trying to draw a rather large animated gif. I have already done so with the simple method:

image (loopingGif, 0 , 0, width, height);
loopingGif.play()

It works, but with my original image I'm having performance issues. So I wanted to put the frames of the gif into an array and play them. But although it seems that the single frames and the delays are correct (the getDelays part is not my piece of code), it is pausing at the wrong part inside my IF/ELSE loop. I uploaded a simple sample gif for testing. Here's the code:

import gifAnimation.*;
PImage[] allFrames;
int[] delays;
int i = 0;

void setup() {  
  size(200, 200);

  //load images into array
  allFrames = Gif.getPImages(this, "http://i.imgur.com/APqsiHv.gif");

  //load delays into array
  delays = getDelays("http://i.imgur.com/APqsiHv.gif");

  // Debugging
  println(delays);
}  

void draw() {
  if (i < allFrames.length) { 
    //draw single frame
    image(allFrames[i], 0, 0, width, height);
    text("frame: " + i, 10, 20);
    text("delay: " + delays[i] + " ms", 105, 20);

    //delay frame with associated delay
    delay(delays[i]); // DOESN'T WORK
    //delay(delays[4]); // WORKS. WHY?
    i++;
  } else {
    i = 0;
  }
}

/* Function getDelays Array
 */
int[] getDelays(String filename) {
  GifDecoder gifDecoder = new GifDecoder();
  gifDecoder.read(openStream(filename));
  int n = gifDecoder.getFrameCount();
  int[] delays = new int[n];
  for (int i = 0; i < n; i++) {
    delays[i] = gifDecoder.getDelay(i);
  }
  return delays;
}

Can someone help me, please?

Alex

Tagged:

Answers

  • Answer ✓

    The delay on all the frames is 200ms, except the middle frame, which is 1000ms. The draw() function does not update until the code within it is completed. So when you draw the middle frame you are also calling the 1000ms delay. The middle frame does not display until the 1000ms delay is complete.

  • Thanks, that helped!

    Meanwhile I coded a workaround which works, but isn't particularly easy to read nor beautiful. I am working on a complete rewrite using millis() and will post that when it's done.

  • edited October 2014

    Here is my rewrite for those that are interested. I would be wondering how this would look like in an object-oriented way. If someone feels like it…

    import gifAnimation.*;
    PImage[] allFrames;
    int[] delays;
    
    int delaysSum; // runtime sum of delays
    int elapsed; // runtime elapsed
    int timer; // initial offset
    int frameCounter = 0; // for addressing frames + delays
    
    void setup() {  
      size(200, 200);
    
      //load frames + delays from gif into arrays
      allFrames = Gif.getPImages(this, "h__ttp://i.imgur.com/APqsiHv.gif");
      delays = getDelays("h__ttp://i.imgur.com/APqsiHv.gif");
    
      // Debugging
      println(delays);
    
      delaysSum = delays[0]; // sum of past delays
      timer = millis(); // save timer to compensate initial offset
    }  
    
    
    void draw() {
      elapsed = millis() - timer; // reset timing to start at 0 ms
    
      // draw image
      image(allFrames[frameCounter], 0, 0, width, height);
      rect(random(200), random(200), 5, 5); // to see it draws constantly
    
      // check if next frame must be played
      if (elapsed > delaysSum) {
        println("playing frame " + frameCounter + ", delay" + delays[frameCounter] + " ms | time " + elapsed + " , next frame @ " + (delaysSum + delays[frameCounter]));
    
        if ( frameCounter < allFrames.length -1 ) {
          frameCounter++; // jump to next frame
        } else {
          frameCounter = 0; // jump to first frame
        }
        delaysSum = delaysSum + delays[frameCounter];
      }
    }
    
    
    /* Function getDelays Array
     */
    int[] getDelays(String filename) {
      GifDecoder gifDecoder = new GifDecoder();
      gifDecoder.read(createInput(filename));
      int n = gifDecoder.getFrameCount();
      int[] delays = new int[n];
      for (int i = 0; i < n; i++) {
        delays[i] = gifDecoder.getDelay(i);
      }
      return delays;
    }
    
Sign In or Register to comment.