FFmpeg: high quality animated GIF?

30,165

Solution 1

I've written a tool specifically for maximum quality:

https://gif.ski

ffmpeg -i video.mp4 frame%04d.png
gifski -o clip.gif frame*.png

It generates good per-frame palettes, but also combines palettes across frames, achieving even thousands of colors per frame.

If you want to reduce the video dimensions, add a scaling filter:

ffmpeg -i video.mp4 -vf scale=400:240 frame%04d.png

If you want to reduce the frame rate, add the fps filter:

ffmpeg -i video.mp4 -vf fps=12 frame%04d.png

You can combine the filters with -vf scale=400:240,fps=12

Solution 2

The key issue is that any gif picture or frame has an extremely limited palette of only 256 of the possible millions of colors in your video.

This is well explained here.

So, fairly recently (2015, version 2.6) ffmpeg got the palettegen and paletteuse filters that can generate better pallettes for each frame.

Therefore, make sure you are using a fairly recent version of ffmpeg.

So, there's your secret and key search term to get you to make high quality gifs in no time - study up on palettegen filters. Reddit beware.

Some references:

ffmpeg 2.6 release notes

ffmpeg docs

superuser

blog.phk.me

Solution 3

shell_exec("/usr/bin/ffmpeg -i video.mkv -r 20 -f image2pipe -vcodec ppm - | convert -delay 5 - output.gif");

I suppose you have no imageMagick installed on your environment, because "convert" is one of IM's tools.

As for the video artifacts, it is caused by the default dithering method in FFmpeg. For best results, I'd recommend floyd_steinberg or sierra2_4a, and maybe bayer with scale set to 3. (Also, there's no such things like "huge" pixels, they are the atomic elements of raster images.)

On the other side, you can achieve better results with ffmpeg only. First, I'd generate a palette of the input video:

ffmpeg -i <your_input.mkv> -filter_complex "fps=10;scale=500:-1:flags=lanczos,palettegen=stats_mode=full" -t 10 palette.png

Then, use this color template to generate the actual gif file:

ffmpeg -i <your_input.mkv> -i palette.png -filter_complex "[0]fps=10;scale=500:-1:flags=lanczos[scaled]; [scaled][1:v] paletteuse=dither=sierra2_4a" -t 10 <output.gif>

You might need to fiddle with the params and the dithering methods to achieve best result. You may also try to generate new palette for each frame, so you can skip the first pass, and use the new option in the paletteuse filter.

Share:
30,165

Related videos on Youtube

David Hope
Author by

David Hope

Updated on July 09, 2022

Comments

  • David Hope
    David Hope almost 2 years

    I'm generating animated a GIF from a video on my server.

    The generated GIF is not really high quality and it looks like the pixels are huge.

    Example:

    example GIF

    This is how I generate the GIF:

    shell_exec("/usr/bin/ffmpeg -i video.mkv -vf scale=500:-1 -t 10 -r 10 image.gif");
    

    I did a search on Google and came across this:

    shell_exec("/usr/bin/ffmpeg -i video.mkv -r 20 -f image2pipe -vcodec ppm - | convert -delay 5 - output.gif");
    

    But the command above doesn't do anything and no output.gif is being generated at all.

    There are some tutorials that I came across but none of them worked for me and some of them involve using ImageMagick which I dont have access to.

    Could someone please let me know if there is a clear way to generate a high-quality GIF using FFmpeg?

  • harry
    harry over 5 years
    Awesome work. I'm exploring imageoptim as a result of seeing the quality of gifski.
  • paradox460
    paradox460 over 4 years
    Just a note: you can combine the two commands into one using a slightly more complex filtergraph: ffmpeg -i <your_input.mkv> -filter_complex "fps=10;scale=500:-1:flags=lanczos,split[v1][v2]; [v1]palettegen=stats_mode=full [palette];[v2]palette]paletteuse=dither=sierra2_4a" -t 10 <output.gif>
  • TigerhawkT3
    TigerhawkT3 over 4 years
    That color space is beautiful, but the resulting file size in my quick test is 3-4x what I get with ffmpeg's default gif encoder. Am I doing something wrong? I'm using the latest Windows exe available from GitHub releases (version 0.8.5).
  • Kornel
    Kornel over 4 years
    It's normal that higher-quality file takes much more space. The best way to reduce gif size is to reduce motion (area that changes between frames) or framerate. You can also try giflossy (gifsicle --lossy).
  • Martin Castin
    Martin Castin over 2 years
    @paradox460 I think your comment should be an answer to make it more visible

Related