How to Turn Pixel Art Sprites into Looping Animations Using Only Free Tools

Last night I pulled up the 16x16 slime sprite I generated with Midjourney on my monitor and stared at it for a while. The colors were nice and the shape was cute, but it just stood there motionless, and something felt off. To put it in a game prototype, it needed at least an idle animation. So at 2 AM, I brewed another cup of coffee and got to work. Here's a write-up of the process.

Preparation

You only need two things: LibreSprite and FFmpeg. LibreSprite is an open-source fork of Aseprite that has nearly all the features you need for pixel animation work. If you already have Aseprite, you can use that instead (you can buy it on Steam or build it from source). FFmpeg is a command-line tool, which can feel a bit intimidating at first, but in practice you only need a line or two of commands.

Preparing the Sprite and Breaking It into Frames

When you open an AI-generated sprite in LibreSprite, it's usually a single layer, single frame. From here, you need to create your animation frames.

Here's the method I use. I duplicate the original frame to create about 4 to 6 frames, then apply subtle variations to each one. For a slime character, that means squashing the body 1px up and down and slightly shifting the highlight position. The key is to keep the amount of change to a minimum. In pixel art, even a 1px difference is highly noticeable, so if you get greedy and move things 3px or more, the character ends up looking like it's having a seizure.

In LibreSprite's timeline panel, set the frame duration to 150 to 200ms and run the preview. If the motion looks natural, move on to the next step.

LibreSprite timeline showing six animation frames of a pixel slime sprite

From Sprite Sheet to GIF

You can export the finished animation directly as a GIF from LibreSprite. Go to File > Export Sprite Sheet to export a PNG sheet, then use File > Save As and select GIF. You can stop here if you like. However, I take it one step further with FFmpeg.

There's a reason for this. LibreSprite's default GIF export has limited dithering options, and the file size optimization leaves something to be desired. With FFmpeg, you can control palette generation directly, which produces much cleaner results.

First, export each frame as an individual PNG (File > Save As, include {frame} in the filename). Then open a terminal and type the following:

ffmpeg -framerate 6 -i frame_%02d.png -vf "palettegen" palette.png
ffmpeg -framerate 6 -i frame_%02d.png -i palette.png -lavfi "paletteuse" -loop 0 output.gif

The first line extracts an optimal palette from the frames, and the second line applies that palette to create a looping GIF. -loop 0 means infinite loop. Adjust the framerate value to match the number of frames and the speed you want. My slime had 6 frames, so setting -framerate 6 gave it a feeling of completing one cycle per second, which was just right.

Split view of FFmpeg terminal output and resulting looping pixel art GIF animation

Putting It in an Actual Prototype

You can use the GIF created this way directly as a sprite animation in Godot or Unity. I've been building a small roguelike in Godot lately, and I import the per-frame PNGs into an AnimatedSprite2D node. Importing as a sprite sheet rather than using the GIF directly is better for engine-side performance.

I watched the finished slime bouncing around as the sun rose outside my Raleigh apartment window. The whole process, including AI sprite generation, took just over an hour. It honestly amazes me every time that you can get results like this with nothing but free tools. Next time, I'm planning to use the same workflow to create an NPC walking animation.

Comments