How to Generate a Palette for FFmpeg GIF Conversion

This guide demonstrates how to extract a dedicated color palette image from a video using FFmpeg to dramatically improve the quality of your output GIFs. Standard GIF conversions often suffer from severe color banding and heavy dithering because the GIF format is constrained to a maximum of 256 colors. By utilizing FFmpeg’s palettegen and paletteuse filters, you can analyze your source footage, create a tailored 256-color palette image, and map it directly to your frames for clean, vibrant results.

Step 1: Generate the Color Palette Image

To build an optimized palette, use the palettegen video filter. This filter inspects all frames in the clip and determines the best representative 256 colors.

Run the following command in your terminal:

ffmpeg -i input.mp4 -vf "fps=15,scale=480:-1:flags=lanczos,palettegen" palette.png

Breakdown of the Command:

  • -i input.mp4: Specifies your source video file.
  • fps=15: Sets the frame rate. Lowering the frame rate from 30 or 60 to 10–15 reduces file size without ruining perceived motion.
  • scale=480:-1:flags=lanczos: Scales the width to 480 pixels and calculates height automatically to preserve aspect ratio (-1), using the high-quality lanczos scaling algorithm.
  • palettegen: Generates a specialized PNG image containing the 256-color palette.
  • palette.png: The output palette image file.

Note: It is crucial to match the fps and scale settings between the palette generation step and the final GIF creation step to ensure color accuracy.


Step 2: Render the GIF Using the Palette

Once you have generated palette.png, pass both the original video and the palette image into FFmpeg, linking them with the paletteuse filter.

Run the following command:

ffmpeg -i input.mp4 -i palette.png -filter_complex "fps=15,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif

Breakdown of the Command:

  • -i input.mp4 -i palette.png: Passes both the source video (input 0) and your palette image (input 1).
  • -filter_complex: Applies multiple filter streams. It resizes and adjusts the frame rate of the video (labeled as [x]), then pairs [x] with the second input ([1:v], the palette image) through the paletteuse filter.
  • output.gif: The final optimized GIF.

Alternative: Generate and Apply in a Single Command

If you do not need to keep the intermediate palette.png file on disk, you can generate the palette in memory and apply it immediately within a single command using split:

ffmpeg -i input.mp4 -filter_complex "fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif

This method splits the scaled video stream into two paths: one generates the palette, and the other uses it to produce the final GIF in one pass.


Fine-Tuning Palette Options

You can append parameters to palettegen and paletteuse to further refine your results:

  • Handling Scene Changes (stats_mode): By default, palettegen builds one palette for the entire video (stats_mode=full). If your video contains drastic scene changes, use palettegen=stats_mode=diff to prioritize moving objects and changing pixels.
  • Dithering Methods: Control dithering in paletteuse with options such as paletteuse=dither=bayer:bayer_scale=3 for a crosshatch pattern, or paletteuse=dither=floyd_steinberg for standard diffusion. To disable dithering entirely for flat graphics, use paletteuse=dither=none.