Animated Gif SlideShow

edited September 2015 in Library Questions

Hi there, I'm trying to display a dozen of animated Gif. I display them one by one : - I load and display the first Gif - after a certain time, I load and display the second gif, - after a certain time, I load and display the third gif, - etc.

The problem is I reach a OutOfMemory error.

How can I fix my code to avoid this ?

import gifAnimation.*; 

Gif loopingGif;
int maxGif;
String dirGif;
int posGif =1;

void setup() {
  maxGif = 85; // I have 85 animated gif to display one by one
  dirGif = "bw/bbg/";
  posGif = 1;
  frameRate(25);
  size(1024, 768);
  imageMode(CENTER);
  background (0);
  loopingGif  = new Gif(this, dirGif+nameGif(posGif)+".gif");
  loopingGif.play();
}

void draw () {
 if (frameCount%200==0) { // every 200 frames (about 4 seconds), I switch to the next gif
   nextImage();
 }
 image(loopingGif, width/2 , height/2);
}

String nameGif(int pos) {
  return nf(pos, 3);
}

void nextImage() {
  if (posGif>maxGif) {
    posGif=0;
  }
  else {
    posGif++;
  }
  loopingGif.dispose();
  loopingGif = null;
  loopingGif  = new Gif(this, dirGif+nameGif(posGif)+".gif"); // The OutOfMemory is here, after 2 gifs loaded
  loopingGif.play();
}

Please, help meeeeeee..

Thanx

Jean

Answers

  • I think loopingGif.dispose doesn't work, neither loopingGif = null

  • Method dispose() should work at least up till Processing 3.0a5.

  • Using dispose() method (on processing 2.2) doesn't work. When monitoring memory used by java, it grows and grows until... OutOfMemory !

    Any ideas ?

  • edited September 2015

    I don't get it either. Most I can think about is forcing an early removal of its ImageCache from the canvas via removeCache(): ^#(^

    loopingGif.dispose();
    removeCache(loopingGif);
    loopingGif = new Gif( // ...
    loopingGif.play();
    

    After all a Gif object is a PImage too. :ar!

  • Even with removeCache(), the memory used by java is growing, growing... Too bad...

  • edited September 2015

    As every Gif gets registered for the dispose event but never gets unregistered after disposing, it can't be garbadge collected.

    Just add unregisterDispose(loopingGif); right after line 38 to get rid of this memory leak. ;)

  • edited September 2015

    Just add unregisterDispose(loopingGif); right after line 38 to get rid of this memory leak.

    @Poersch, Gif's dispose() method already does that:
    https://GitHub.com/extrapixel/gif-animation/blob/master/gifAnimation/src/Gif.java#L83

    public void dispose() {
      parent.unregisterDispose(this);
      stop();
      runner = null;
    }
    
  • edited September 2015

    @GoToLoop: And now look into the source from the downloaded library:

    public void dispose() {
        // fin
        // System.out.println("disposing");
        stop();
        runner = null;
    }
    

    Download page

  • edited September 2015

    @janolap1, in case your ".gif" files don't have transparency, you can replace image() w/ set().
    Since the latter doesn't setCache() like the former. ;;) https://Processing.org/reference/set_.html

    Otherwise, since last attempt wasn't enough, you gotta be more radical! >-)
    Besides removeCache(), invoke System.gc() as well: *-:)
    http://docs.Oracle.com/javase/8/docs/api/java/lang/System.html#gc--

    loopingGif.dispose();
    removeCache(loopingGif);
    loopingGif = new Gif( // ...
    loopingGif.play();
    System.gc();
    

    And in order to make sure no ImageCache might still be hanging around,
    within draw(), call removeCache() after each image() involving any Gif object: \m/

    image(loopingGif, width>>1 , height>>1);
    removeCache(loopingGif);
    
  • @GoToLoop: Did you even download the library and test your code (or mine)..?

    While it's true that there is no memory leak in version 2.4 on github, all download links point to the 7 year old version 2.3. Just have a look at my last post.

  • edited September 2015

    @Poersch, indeed you're right! Nice find! :D
    Version installed is still 2.3. But I was trusting it was the same as latest 2.4 from GitHub! X_X

    That's very serious! It means this Gif library had this bug since its inception! :-&
    And its developer is still holding back such critical fix dunno why! [-(

    Inside Gif's constructor, it calls parent.registerDispose(this);.
    But completely forgotten to call its corresponding parent.unregisterDispose(this); inside dispose()! 8-}

    Even worse, both registerDispose() & unregisterDispose() are deprecated in Processing 2.
    And both got removed in Processing 3. Therefore both need to be replaced w/ registerMethod() & unregisterMethod().

    Doing so removes compatibility for Processing 1. But still maintains it for both 2 & 3! :D

  • Did you even download the library and test your code (or mine)..?

    Sorry I haven't! I've only studied the source code there in GitHub and concluded it was OK! X_X

  • edited September 2015

    @GoToLoop: No problem! :)

    Btw.: System.gc() will automatically be called from the JVM before throwing an OutOfMemory error. It only makes sense to force garbadge collection if you want to prevent the garbadge collector from freeing too much memory at once, which could lead to stuttering (unstable frame rate).

    I'll link @extrapixel to this thread. Hope it's the right one. :D

  • edited September 2015

    I don't believe System.gc() wouldn't stutter even as an inch as creating a new Gif object.
    Which involves loading some ".gif" file and decoding it into multiple PImage objects! ~:>

    IMO, that instantiation should happen inside a separate thread() if possible: :P
    https://Processing.org/reference/thread_.html

  • edited September 2015

    In my testcode one Gif object occupies 450MB of RAM. Although I didn't want to imply that garbadge collecting some big Gif objects would lead to stuttering, as the size of the garbadge collected objects generally doesn't matter, it's more the object count and fragmentation. My statement is, that it just makes no sense to call System.gc() in cases like this at all.

    Jub, he could display one Gif, while loading the next.

  • Jub, he could display one Gif, while loading the next.

    Yup, I've done that for Movie class in some older forum threads. ;)

  • edited September 2015

    Hey. I fixed most Processing v3 compatibility issues and pushed to Github. https://github.com/01010101/GifAnimation Not sure about the Memory pb though. Haven't look at it yet.

  • edited September 2015

    @01010101, AFAIK the compatibility issues were already fixed.
    It's just that the version downloaded by the PDE (v2.3) wasn't the latest (v2.4).
    In short, by using v2.4, GifAnimation library would still work for both Processing 2 & 3 versions.

  • Of course, v2.4 still has the problem of using the deprecated registerDispose() & unregisterDispose().
    In order to work w/ both Processing 2 & 3, they need to be changed as registerMethod() & unregisterMethod() as I said in my previous post:

    Even worse, both registerDispose() & unregisterDispose() are deprecated in Processing 2. And both got removed in Processing 3. Therefore both need to be replaced w/ registerMethod() & unregisterMethod().

    Doing so removes compatibility for Processing 1. But still maintains it for both 2 & 3!

  • @gotoloop the change to "registerMethod" was part of my changes. Also made changes to use typed ArrayList, removed unneeded casts and cleaned the Javadoc comments

  • edited January 2018

    Hi,

    this discussion is as old as a white beard, but maybe some of you are still willing to help (@GoToLoop, @01010101) !? I am using 01010101's Github version of the animation library with P3.3.6 and still get the OutOfMemory exception. Was this fixed by somebody in 2015?? I tried to use all this fancy cache cleaning functions mentioned above but nothing worked for me. As I understood the situation, all this was and is due to problems in the GifAnimation library. Is there any feasible way today to work around this working within the processing ID??

    Thank you so much! Tim

Sign In or Register to comment.