Convert Processing Sketches into Animated GIFs
This is another quick tutorial on how to make GIFs in Processing.
The recommended approach is to use the gifAnimation library. However, I’ve found that the GIFs created by it can be a little glitchy. I’ll quickly show this approach and then show some of the glitches I’ve encountered. I’ll end by mentioning two more reliable approaches that I’ve found: one using ImageMagick and another using FFmpeg.
Approach 1: GIFs with gifAnimation
Import the gifAnimation library. If you don’t have it installed, select “Add Library” from the “Import Library” submenu within the Sketch menu. You can also get it directly from Github if you want.
This should add the following line to the top of your sketch:
import gifAnimation.*;
Now create a GIF variable and set it up.
GifMaker gifExport;
gifExport = new GifMaker(this, "out.gif");
gifExport.setRepeat(0); // 0 means "loop forever"
gifExport.setDelay(30);
gifExport.addFrame();
Finally, finish your GIF and have Processing write it to the final file
using the finish()
function.
gifExport.finish();
I have a utility class that I use for this, which looks like the following:
import gifAnimation.*;
class GIF {
GifMaker gif;
GIF(PApplet app, String filename) {
gif = new GifMaker(app, filename, 100);
gif.setRepeat(0); // 0 means endless loop
}
void addFrame(int delay_in_frames) {
gif.setDelay(delay_in_frames);
gif.addFrame();
}
void save() {
gif.finish();
println("Done!");
}
};
To use this, here’s a simple sketch that animates a red circle horizontally across a black background.
GIF g;
int i = 0;
void setup() {
size(500, 200);
g = new GIF(this, "out.gif");
frameRate(30);
fill(255, 0, 0);
noStroke();
}
void draw() {
background(0);
ellipse(i, height/2, 200, 200);
if (i >= width) {
/* Add a 2 second delay for the last frame */
g.addFrame(2000);
g.save();
noLoop();
} else {
/* Add a framerate-proportional delay for other frames */
g.addFrame(1000/30);
println("Added frame " + i);
}
i+=20;
}`java
Issues with gifAnimation
As I mentioned before, I’ve encountered some glitches with the gifAnimation
library and it’s particularly problematic when using smaller shapes in your
sketches. My guess is that the encoding performed by the library throws out
small shapes somehow…
Here are the resulting GIFs when drawing a circle with 10, 100, and 200 pixel diameters:
Notice all that blinking in the first two? It’s not clear why this occurs or if there is some issue with my approach, but I haven’t found a way to fix it thus far. I’ll update this page if I do.
Approach 2: Generate GIFs with ImageMagick
Instead, the better solution I found, which is unfortunately also more involved, was to save PNGs for each frame and use ImageMagick to generate the final GIF.
Download ImageMagick for your OS here.
Now open up a terminal for your OS and navigate to the folder containing your
saved PNGs (use saveFrame("#######.png")
to do this in Processing). Type
the following command:
convert -delay 30 *.png +repage -loop 0 out.gif
Approach 3: Generate GIFs with FFmpeg
You can also generate GIFs using FFmpeg. I use the following script taken from this nice tutorial on getting high-quality GIFs using FFmpeg
#!/bin/sh
palette="/tmp/palette.png"
filters="fps=15,scale=320:-1:flags=lanczos"
ffmpeg -v warning -i %05d.png -vf "$filters,palettegen" -y $palette
ffmpeg -v warning -i %05d.png -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $1)
Remember to save
your frames with saveFrame("#####.png")
, using five hash signs to match the
%05d.png
in the script. Now just save the script as gif.sh
and invoke it
within the folder containing the PNGs and give it an output file name as an argument:
$ cd <folder-with-PNGs>
$ ./gif.sh out.gif
Have fun creating GIFs!