如何修复使用 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 = 2
或 3
或编写直接流式传输的脚本,请复制您的 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
的其他位是个好主意,因为没有人知道其中可以及时编码什么...
我想将带 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 = 2
或 3
或编写直接流式传输的脚本,请复制您的 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
的其他位是个好主意,因为没有人知道其中可以及时编码什么...