Removing crosshatch when creating a GIF in ffmpeg

Here's how to create a GIF from an mp4 with ffmpeg:

ffmpeg -i my-video.mp4 my-gif.gif

The problem is, if you turn up the brightness on your display and look closely at the GIF, there’s a visible crosshatch pattern overlay that wasn’t in the original video:

bear-to-contentful-default-short

To remove this, you need to do some fancy manipulation.

MP4 to GIF, without dithering

The reason why the crosshatch exists is something called dither:

Dither is an intentionally applied form of noise used to randomize quantization error , preventing large-scale patterns such as color banding in images.

So ffmpeg uses dithering algorithms to avoid visual errors and make the output more predictable.

To remove it, ffmpeg has these really neat features called palettegen and paletteuse, which allow you to create a color palette of 256 pixels from your video, define a dithering algorithm, and use it when creating your GIF. Here’s how to do that:

ffmpeg \
  -i my-video.mp4 \
  -vf palettegen \
  palette.png

ffmpeg \
  -i my-video.mp4 \
  -i palette.png \
  -filter_complex paletteuse=dither=none \
  my-gif.gif

bear-to-contentful-without-dither-short

If you look closely again, you can see the crosshatch is gone!

Note this command actually contains two commands that you can run separately. The first command creates a color palette from your MP4, the second uses your color palette and a few other filters to make a GIF.

MP4 to GIF, with many more filters

Finally, I want to reduce the file size, resize the GIF, and crop the resized GIF too. With the -filter_complex flag, you can add as many filters as you want with comma-separation:

ffmpeg \
  -i my-video.mp4 \
  -vf palettegen \
  palette.png

ffmpeg \
  -i my-video.mp4 \
  -i palette.png \
  -filter_complex "fps=15, scale=320:-1, crop=in_w:in_h-18:0:18, paletteuse=dither=none" \
  my-gif.gif

The added filters include:

And there you have it! Copy and paste away, future self.


Thanks for reading! Go home for more notes.