如何修复使用 Graphicsmagick 收集的损坏的 alpha 通道(像素卡住)的 .gif?

How to fix .gif with corrupted alpha channel (stuck pixels) collected with Graphicsmagick?

我想将带 alpha 通道的 .avi 转换为 .gif。
首先,我使用

ffmpeg -i source.avi -vf scale=720:-1:flags=lanczos,fps=10 frames/ffout%03d.png

使用 aplha 通道将 .avi 转换为 .png 序列。
然后,我使用

gm convert -loop 0 frames/ffout*.png output.gif

收集.gif.
但似乎 output.gif 的像素只是在透明区域顶部呈现不透明的东西时卡住。

举个例子:

如您所见,红心和爆炸不会被去除渲染。

P.S。 FFMPEG 输出(.png 上的集合)没问题。

我不使用 Graphicsmagick,但是你的 GIF 有图像 disposal mode 0(没有动画)。你应该使用处理模式 2(清除背景)或3(恢复以前的图像)都适用于你的GIF.该处理存在于 Packed 值中每个帧的 gfx 扩展中。

因此,如果您可以尝试将编码器配置为使用 disposal = 23 或编写直接流式传输的脚本,请复制您的 GIF 并更改 Packed 逐帧 gfx 扩展块的值。类似这样:

如果您需要有关脚本的帮助,请查看:

  • Decode data bytes of GIF87a raster data stream

当我在你的 GIF 上使用处置 2 尝试这个(C++ 脚本)时,我得到了这个结果:

C++ 中的处置方式更改如下:

struct __gfxext
    {
    BYTE Introducer;        /* Extension Introducer (always 21h) */
    BYTE Label;             /* Graphic Control Label (always F9h) */
    BYTE BlockSize;         /* Size of remaining fields (always 04h) */
    BYTE Packed;            /* Method of graphics disposal to use */
    WORD DelayTime;         /* Hundredths of seconds to wait    */
    BYTE ColorIndex;        /* Transparent Color Index */
    BYTE Terminator;        /* Block Terminator (always 0) */
    __gfxext(){}; __gfxext(__gfxext& a){ *this=a; }; ~__gfxext(){}; __gfxext* operator = (const __gfxext *a) { *this=*a; return this; }; /*__gfxext* operator = (const __gfxext &a) { ...copy... return this; };*/
    };

__gfxext p;
p.Packed&=255-(7<<2);   // clear old disposal and leave the rest as is
p.Packed|=     2<<2;    // set new disposal=2 (the first 2 is disposal , the <<2 just shifts it to the correct position in Packed)

保留 Packed 的其他位是个好主意,因为没有人知道其中可以及时编码什么...