[FFmpeg-user] Lossless and colour preserving pix_fmt?
from.ffmpeg-user at jdlh.com
Thu Jan 11 05:52:59 EET 2018
On 2018-01-07 21:29, Jim DeLaHunt wrote:
> Hello, ffmpeg'rs:
> I'm trying to overlay animated GIFS onto one white background, with
> some text at the top. I'm looking for an incantation which a) does
> the job and b) leaves all the colours of the animated gifs unchanged.
> What options tell ffmpeg not to mess with the colour values, not to
> change colour spaces, not to reduce precision of colour coordinate
The best answer to this appeared in an answer to SuperUser question,
/Lossless universal video format /
Preserve colour space? Sorry, none. The Animated GIF colour values are
defined as 24-bit RGB values in sRGB space. As far as I can tell it's
hard to get FFmpeg to use RGB for its operations, it really pushes you
to YUV (luminance and two chroma values). However, the YUV values are
24-bits. I speculate that perceptually, a conversion from sRGB to YUV
back to sRGB will be lossless.
You need to prevent lossy compression by the pixel format (encoder). The
*libx264* encoder with the option *-crf 0* provides lossless compression.
You also need to prevent downsampling of the U,V components of the YUV
colour value. This is explained well at /Recommended 8-Bit YUV Formats
for Video Rendering/
by Gary Sullivan and Stephen Estrop, Microsoft Corporation, 2002 and 2008.
The term *YUV444* refers to Y,U,V colour space, and 4:4:4 downsampling,
i.e. U,V at same resolution as Y.
*YUV420* refers to U,V at 1/2 horizontal x 1/2 vertical = 1/4 overall
resolution as Y. That works against lossless encoding. Be sure your
encoding is using a pix_fmt like YUV444. As far as I can tell, *libx264
-crf 0* defaults to YUV444 pixel format.
Then Carl Eugen points out something else important: how to generate a
good palette for the output GIF.
On 2018-01-08 04:25, Carl Eugen Hoyos wrote:
> Depending on the input file, this may not be possible.
> To create a (nice looking) gif - with most likely different colours - you
> need the palettegen and paletteuse filters.
I was making an assumption that when ffmpeg saved to GIF format, it by
default created a palette which would render the animation well. It
looks like that's incorrect, and the *palettegen* filter
<http://ffmpeg.org/ffmpeg-all.html#palettegen-1> can generate a
better palette. Maybe there's some strong technical reason for this,
such as the GIF output having to created a palette based on information
only from the first frame, while palettegen can gather information from
In any case, here's how I addressed the problem. I broke the task into
1. Read the animated GIF in, store as libx264 -crf 0 format in a
2. Run the x264 video through palettegen, generating a palette as a PNG
3. Read the x264 video in again, passing it and the palette through the
paletteuse filter, saving as animated GIF.
4. Delete the x264 video and the palette.
This gave me acceptable quality. Here's roughly the commands I used:
% ffmpeg -i animated_blue_12.gif -filter_complex "
color=color=white at 1.0:size=696x400,
drawtext=fontsize=20:font=Arial:x=10:y=10:text=Hamburgefons Hamburgefons Hamburgefons
[0:v] setpts=PTS-STARTPTS [gs1];
" -c:v libx264 -crf 0 -preset ultrafast -y temp.mkv
% ffmpeg -i temp.mkv -vf palettegen palette.png
% ffmpeg -i temp.mkv -i palette.png -filter_complex paletteuse -y blue+text.gif
% rm temp.mkv palette.png
I hope that's helpful for someone! Thanks,
—Jim DeLaHunt, Vancouver, Canada
--Jim DeLaHunt, jdlh at jdlh.com http://blog.jdlh.com/ (http://jdlh.com/)
multilingual websites consultant
355-1027 Davie St, Vancouver BC V6E 4L2, Canada
Canada mobile +1-604-376-8953
More information about the ffmpeg-user