Gifs generated with saveGif() only contain a single color

Hey friends, long time no see!

I’ve been pretty excited about the saveGif() function, but I’m having trouble getting it to work as expected.

Here’s some code I’m trying:

let colors = ['red', 'yellow', 'orange', 'green', 'blue', 'purple'];

function setup() {
  createCanvas(400, 400);
  background(32);
  noSmooth();
}

function draw() {
  noStroke();
  fill(random(colors));
  circle(random(width), random(height), random(10, 20));
}

function mousePressed(){
  saveGif('test', 5);
}

(View the sketch in the p5.js editor here)

The screen fills up with randomly colored circles (I limited the colors in case the issue is related to the gif color palette limitations), and when I press the mouse, I expect a gif of those circles to be saved.

Here’s the GIF exported using a tool called Screen to Gif:

animation of randomly colored circles

However, if I press my mouse to trigger the saveGif() function, I get something like this:

animation of single-colored circles

The gif appears to only contain a single color, although I think maybe I have a mix of yellow and black circles. It might also be worth noting that it’s a different color every time I click:

animation of red circles

The replies to the tweet announcing this feature seem to include a mix of folks with multi-colored gifs, and folks with gifs like mine.

I’ve tried both Firefox and Chrome on Windows, and Chrome on Android.

Can anybody help me understand what’s happening? Is this a known behavior of the saveGif() function? Can I do anything to make sure my gifs export correctly?

1 Like

Hi @Kevin,

Hmmm! Never used the saveGif yet, but I’ve tested your code and have the same issue.
Nevertheless, if I switch to WEBGL renderer, it seem to work better (ie. as expected !?) …

let colors = ['red', 'yellow', 'orange', 'green', 'blue', 'purple'];

function setup() {
  createCanvas(400, 400, WEBGL);
  background(32);
  noSmooth();
  noStroke();
}

function draw() {     
  fill(random(colors));
  circle(random(width)-width/2, random(height)-height/2, random(10, 20));
}

function mousePressed(){
  saveGif('test', 5);
}

Maybe you should raise an issue on p5js github with your code example for clarification …

Cheers
— mnse

2 Likes

Thanks for the reply. Interestingly, if I switch to WEBGL I only see black, no circles.

Edit: It turns out that in WEBGL mode, all of my circles draw in the lower-right quadrant. If my screen magnification is set to 100%, then the GIF shows the circles in the lower-right quadrant.

circles in lower-right quadrant

If it’s set to 150% (the default), then I don’t see the circles in the saved gif.

no cicles

I filed a bug here: Gifs generated with saveGif() only contain a single color · Issue #5881 · processing/p5.js · GitHub

Hi @Kevin,

That’s a normal behavior. This is because the origin (0,0) represents the center of the screen. If you want to change use the translate function to shift it back.

translate(-width/2,-height/2,0);

Cheers
— mnse

1 Like

Ahh thanks for clearing that up!

Btw thanks to Dave Pagurek, looks like there’s a fix for the color bug:

According to its bug pull explanation: :bug:

This fix is gonna increase the gif file’s size even for sketches that didn’t have this bug b/c it won’t use a cached palette anymore. :art:

Perhaps they should maintain the old palette cache buggy behavior as an extra { option } 3rd parameter for sketches that don’t need this fix and prefer a smaller gif file. :thinking:

How much of a size increase is this going to cause?

If the size increase is too large, I could see a few other options, including modifying the documentation to explain that your first frame should contain all of the colors you’ll need in your palette.

No idea! I only know that less usage of palettes the lesser the gif’s file size. :man_shrugging:

It was just an advice to keep the old behavior via the 3rd parameter, which is an object argument that customizes the behavior of the function. :bulb:

I left a comment over in the PR: Fix palette generation bugs in saveGif() by davepagurek · Pull Request #5883 · processing/p5.js · GitHub

1 Like

Hey everyone! I added a reply in the PR, but I’ll also add it here. tl;dr the palette size should be the same as before if you didn’t have this issue with your first frame not having all the colors :slight_smile:

If your gif only had one color on the first frame, this will probably increase the file size as now the gif’s palette will include the whole animation’s colours, but for other sketches, I think the file size will remain the same. The caching I was mentioning happens when mapping input colors (uncompressed, from the original sketch) to the 256-color gif palette. With or without caching, it still gets mapped to the same palette size; the cache is just there to remember what palette color an input color mapped to so that we don’t have to check again. The old code compressed the input colors a little in order to make a cache key, and the new code doesn’t. This means that, while constructing the gif, the cache JS object will use more browser memory than before, but since that isn’t part of the outputted gif, the file size should be effectively the same.

2 Likes