[WARNING: Flickering images] saveGif() inserting blank (black) frame when triggering in setup()

Hey folks,

The reference documentation says that you can call saveGif() during setup() or in an event function. I’m having an issue with a black frame when calling it during setup() and I’m trying to figure out if this is a me thing or a saveGif() thing. This doesn’t happen when it’s called in an event function (like keyPressed()).

  • Interestingly, when saveGif() is in setup(), it seems that the first actual frame it records is frame 2 (according to the frameCount variable, so perhaps it’s only rendering after the first time through draw()?)
  • The workaround I’m using is to turn off the loop with a noLoop() call during setup() and then turn the loop back on during the keyPressed() event after saveGif() has been called.

I haven’t dug into the source for the saveGif() function, but I wanted to ask here first in case I’m making a silly mistake somewhere.

I’ve put a bunch of my testing below. (NOTE: OOPS I can only embed one image)

  • If I trigger saveGif() in my setup(), the resulting gif has a single black frame, which causes an annoying flicker on repeat.
    saved (22)
function setup() {
  createCanvas(400, 400);
  saveGif('saved', 2);
}

function draw() {
  background(220);
  circle(width/2, height/2, 100);
}
  • This happens likewise happens even if a delay is set or units are changes to ‘frames’
function setup() {
  createCanvas(400, 400);
  saveGif('saved', 60, {delay:30, units:'frames'});
}

function draw() {
  background(220);
  circle(width/2, height/2, 100);
}
  • If saveGif() is set to record a single frame during setup(), it records a black frame:
function setup() {
  createCanvas(400, 400);
  saveGif('saved', 1, {units:'frames'});
}

function draw() {
  background(220);
  circle(width/2, height/2, 100);
}
  • If saveGif() is triggered during a keyPressed() event, it functions as intended (though it still doesn’t start at frame 1, according to frameCount):
function setup() {
  createCanvas(400, 400);
  noLoop();
}

function draw() {
  background(220);
  circle(width/2, height/2, 100);
}

function keyPressed() {
  saveGif('saved', 2);
  loop();
}
1 Like

you could start by repeating this line in setup

function setup() {
  createCanvas(400, 400);
  background(220);
  saveGif('saved', 2);
}

I always do this, because setup() seems to show one frame at its end before draw() starts

Remark

I imagine you could also say

function draw() {
  background(220);
  if(firstTime) {
    saveGif('saved', 2);
    firstTime=false; 
  }
  ......

with boolean firstTime=true; before setup() - not tested

I appreciate you taking a look! I gave both those solutions a shot without success.

  • Of note, the black frame is completely black. This suggests to me that something is happening to the first frame where it just tosses out the frame data.
  • The black frame doesn’t only happen at frameCount === 0 or 1, it’s whatever the first frame is, so long as saveGif() is triggered in one of setup() or draw().

Since it works when triggered in an event function, could it have something to do with the context where it’s called? With saveGif() being an async function, maybe the main loop isn’t playing nicely with saveGif() when saveGif() starts running?

1 Like

Hello @jernwerber,

Related discussion:
https://www.deconbatch.com/2022/11/savegif.html

The discussion above makes a reference to this:

It is not recommended to write this function inside setup, since it won’t work properly.

I found the above quote here but not on website:

saveGif() issues on GitHub:
https://github.com/processing/p5.js/issues?q=saveGif

:)

Thanks for all this, @glv! I was bamboozled by the p5.js reference page on saveGif() which doesn’t include the caveat not to use saveGif() in setup:

This may be called in setup, or, like in the example below, inside an event function, like keyPressed or mousePressed.

Not sure if it’s an intentional difference or an oversight, but I’ll open an issue if I can’t find an indication that the change was made on purpose.

1 Like