GIF Compression Techniques
Oct 16, 2015, 9:00:47 AM
This article discusses various animated GIF compression techniques I came across while creating and publishing my animations for the current chapter of This Mortal Coil, "The Miracle." A lot of my work is done using GIMP 2.8 for cutting animated GIFs. Read on if you want to learn how to cut the size of your GIFs down and also adjust the playback time.
Above, you see just a still shot from "The Miracle" of Kamiko catching the moon. The original file is about 43 mb. As you can imagine, that's not great for downloading over a browser (esp. a mobile device), and for this page, since it's at 1140 x 1608 pixels when compressed it comes down to 12 mbs. Still not great for downloading from a mobile device...you'll definitely want wi-fi, but I'll use this page as a discussion for how I compressed it from 43mb to 12mb.
Making the Page
This page of the comic is 64 frames of glorious animation. It is one giant piece, and maybe too giant for its own good.
Here's how it's constructed: The background is painted and Kamiko, Hana, Jade, and some of the foreground are separated out so they can be layered on top of one another. This way I could insert the animated frames of the butterflies inbetween.
The butterflies are rendered using Blender. You can see my previous tutorial "Blender, Butterflies, and Boids" for an explanation. Once I got the primary asset (i.e. butterfly) done, and I learned enough of the particle system, a lot of the setup became easy, so making the animations in Blender wasn't as time consuming. To help me render the animated frames, I used my desktop. Blender can utilize the GPU to speed up rendering times. The Surface Pro 3 doesn't have that capability, and for a render like this we're talking about the difference of a few minutes per frame on the Surface versus a few seconds per frame on desktop with a decent graphics card.
The particle setup uses boids and a goal to allow them to flock towards the ground. A vortex forcefield causes the boids to fly in a spiral. It kinda works. When I cut the animation, I had to do every 5th frame since it was a 300 frame sequence. That's partially why it looks choppy. To help compensate (a bit) I scaled up the butterfly's animation to slow it. This way when I rendered each fifth frame, the flapping motion wouldn't be choppy. Being an animated GIF, I'm limited in what I can do.
You know, I might try and make an animation with all 300 frames and make a video of it. Wouldn't that be neat?
GIMP: Optimize for GIF
With the page composited and rendered using my animation python script in GIMP, I could cut the final GIF, which ended up being 43 mbs.
In the past I would take my GIFs to EZGif.com and use their optimizer. This worked for the other pages, but there's one problem: they only allow uploads up to 16 mbs. I had to investigate other solutions on my PC. Luckily, I stumbled across the Optimize functionality in GIMP.
In GIMP goto the Filter Menu, and then from there Animation->Optimize (for GIF). You don't have to do anything else, it'll go through your GIF and run some optimization and pop out a new version of it. I don't know too much about what it's doing, but if you view the individual layers, you can probably get an idea. It seems to go through the animation and see which parts of the image are the same over frames and cuts out the rest of the static pixel data, so when the animation is run everything looks fine.
This can save you a lot, especially if you don't have a ton of moving objects on screen. It's clever enough to make those bits static and just animate the other parts. For this page of "The Miracle" it cut it down from 43 mb to 25mb. 42% reduction in filesize. Not a bad saving, but we could go even further.
You can reduce the number of colors in the GIF palette to save more memory.
Steps to compress your palette in GIMP:
- Turn your GIF from an indexed image into an RGB image. In the menu goto Image->Mode->RGB.
- Reconvert your image into an indexed one. Image->Mode->Indexed. You will get a dialog and from there you can play with your palette settings.
You can try any of the options to best suit your needs. I usually do the first one: Generate optimum palette. You can even specify how many colors you want in the palette and it'll generate around that number. You can try web-optimized palette and it'll generate something that's fairly decent. I don't care for dithering since I don't like how it looks. Hit Convert and let GIMP process for a bit and then it'll spit out a new layered image file that you can view.
If you want to see the size of your reduced palette go to Image->Image Properties. There you will find the metadata about your image and it'll show you the palette size.
Export your image and hopefully, you'll see a filesize reduction. In my case, I went from 25 mb to 12mb.
Further Size Reduction
Is your GIF still too big? You can consider cropping your image or rescaling it to a smaller resolution. To rescale in GIMP goto Image->Scale Image. You can select a part of your image and crop it as well. For my purposes, all pages of the comic are 1140 x 1608 pixels, which means I'm locked at that size, so 12mb is about as low as I go.
I can also take the image to EZGif.com and try and try another compression trick there. I didn't know this, but GIFs can do lossy compression. I didn't get a huge saving, so I'm just sticking with the 12mb file.
Another way to reduce your GIF size is to remove frames. EZGif has options to remove the 2nd, 3rd, or 4th frames of your GIF. A warning about this: If you've done the GIMP optimization above, it breaks your image into parts, and if you try a frame removal, you'll immediately see your GIF turn into a mess of pixels because it is depending on every frame to be there to make the full image. If you want to remove frames go back to your original GIF asset and run that through EZGif or just go into GIMP and pull out the frames you don't want. You may find that your animation runs faster or is choppier. You can probably adjust the time between each frame to get closer to what you originally had (if timing is something you are trying to preserve). Then you can run the optimize for GIF and palette reduction to get those savings.
Playback Time Adjustment
Another thing you could do to extend your animation is to change the wait time between frames. I did this for some animated ads I made, and in GIMP this is easy to do. In the layers you'll see that each frame has the number of milliseconds listed next to it. You can double-click on the name in the layer, and adjust the milliseconds, by writing how many milliseconds you want, and export your animation. This is good if you have a frame you want to hold for a long time. Here's an example of one of my adverts:
After I composted the animation using my usual tricks (python, Manga Studio, Gimp, etc...), I adjusted the timing via GIMP's layers to get the effect of stopping on the text and then on her face after the butterfly transition. In the diagram below, if you look at the small images of each layer you can see that I've also done the optimize for GIF via GIMP as well. This gives me a longer animation but a small filesize.
If you reduce your color palette too small, you might find that the compression algorithm might muddy your colors. I had that happen where the red in this image became gray when I chopped the palette down to 16-24 colors. Experiment and push it to see how far you can go with your compression.
There's also some images that I needed to compress down so I could get them to fit in Tapastic's 2 mb file size limit and after running a bunch of compression tricks, I began to see various artifacting in the animated GIF. I don't know what I could really do about that since I'm pushing it to an extreme.
I know that we're all on data plans when out and about, so you don't want to visit This Mortal Coil and suddenly download a 12mb file.
Unfortunately, the Mortal Coil website has no way of handling this. There are Wordpress plugins that will allow you to play a GIF when rolling over or clicking on it, but the issue for me is that I don't know how that will interact with my custom comic reader. My custom reader lets you pan through pages via touch, tap on them to advance, etc. If I add this plugin it could break it, which wouldn't be cool for me.
The only option I can think right now is that, on the server side, I could do a PHP query, and discover if you're on a mobile device, and then just send the browser a static image. I'd have to add a field to the custom post type I created to handle a static image and pull that data over the animated GIF (main image). It's on my TODO list and it will probably not be done this week.
So there you have it, everything I know about handling animated GIF compression. If you happen to use this article to help you compress your GIF, link me to it in the comments, especially if it's your own animation. I'd love to see it.
If you have further questions on compression techniques, or if you've got some better compression ideas for GIFs, then I'd love to hear it.