3

We use gifs for our blog extensively. We used to embed tenor nano gifs(90px height maintaining aspect ratio, used for GIF previews and shares on mobile) in it. Now we wanted to create our own gifs and are using the following command to convert mp4 to gif while maintaining the properties of tenor's nano gif. using ffmpeg version 4.1.4

ffmpeg -i input.mp4 -filter_complex "[0:v]fps=10,scale=-1:90:flags=lanczos,split [a][b];[a] palettegen [p];[b][p] paletteuse" -y output.gif

But we observed a huge difference in size between the gif we created and the one created using tenor.

[Original MP4] - 845KB

Tenor Nano gif - 42KB

ffmpeg gif - 106KB

We even tried changing dithering algorithm to further reduce size but it ended up adding noise and damaged the gif quality.

paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle

We tried tweaking colour quantization in gifsicle as well but it was of no use

gifsicle --resize _x90 --colors 256 --color-method diversity --dither=ordered --resize-method sample input.gif > output.gif

Are we missing anything?

Hastur
  • 19,483
  • 9
  • 55
  • 99

1 Answers1

0

Quick solution

You can use the option -fuzz.

convert input.gif  +dither -coalesce -fuzz 10%  -remap input.gif[0] -layers 'optimize' output.gif

enter image description here
This is the result of the previous command line on your ffmpeg.gif file.
The size is comparable (45912 vs 43049 of your Tenor Nano.gif) and depends heavily on the fuzz parameter: with 15% it is 36951...

From man convert

-fuzz distance       colors within this distance are considered equal

What where we missing

From identify of your gif files you can see that

# identify input.gif
input.gif[0] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.010u 0:00.002
input.gif[1] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.010u 0:00.003
input.gif[2] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.010u 0:00.003
input.gif[3] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.010u 0:00.003
...

Notice all the +0+0s for each frame that is the same size

Tenor_Nano.gif[0] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[1] GIF 82x85 90x90+6+5 8-bit sRGB 256c 0.000u 0:00.002
Tenor_Nano.gif[2] GIF 89x85 90x90+0+5 8-bit sRGB 256c 0.000u 0:00.002
Tenor_Nano.gif[3] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[4] GIF 88x89 90x90+2+1 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[5] GIF 89x90 90x90+1+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[6] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[7] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[8] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[9] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[10] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[11] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[12] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[13] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[14] GIF 90x90 90x90+0+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[15] GIF 1x1 90x90+89+89 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[16] GIF 89x90 90x90+1+0 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[17] GIF 86x86 90x90+4+4 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[18] GIF 90x88 90x90+0+2 8-bit sRGB 256c 0.000u 0:00.001
Tenor_Nano.gif[19] GIF 90x87 90x90+0+3 8-bit sRGB 256c 0.000u 0:00.001

Note that not all are +0+0s, frames have different sizes, there is even a 1 pixel frame [15] GIF 1x1 90x90+89+89.

So a better optimization when a portion of the image has no need to be modified... therefore, you can use the -fuzzy option to not touch larger portions of the image and have a smaller final size.

output.gif[0]   GIF  90x90  90x90+0+0   8-bit  sRGB  256c  0.010u  0:00.002  
output.gif[1]   GIF  85x85  90x90+4+5   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[2]   GIF  88x80  90x90+2+10  8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[3]   GIF  86x84  90x90+4+6   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[4]   GIF  84x84  90x90+6+6   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[5]   GIF  81x85  90x90+6+5   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[6]   GIF  70x85  90x90+20+5  8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[7]   GIF  44x83  90x90+22+7  8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[8]   GIF  87x81  90x90+3+9   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[9]   GIF  84x84  90x90+6+6   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[10]  GIF  81x83  90x90+4+6   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[11]  GIF  86x84  90x90+4+6   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[12]  GIF  66x83  90x90+2+7   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[13]  GIF  83x82  90x90+5+7   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[14]  GIF  85x83  90x90+5+7   8-bit  sRGB  256c  0.000u  0:00.002  
output.gif[15]  GIF  70x83  90x90+20+7  8-bit  sRGB  256c  0.000u  0:00.001  
output.gif[16]  GIF  89x84  90x90+0+6   8-bit  sRGB  256c  0.000u  0:00.001  
output.gif[17]  GIF  66x82  90x90+23+8  8-bit  sRGB  256c  43838B 
Hastur
  • 19,483
  • 9
  • 55
  • 99