任何人都可以告诉我为什么这会生成仅黑色的动画gif吗?
代码还会在内存生成的gif中输出每一个,以表明它们是不同的
public static void Test()
{
Image<Rgba32> img = null;
Image<Rgba32> gif = null;
TextGraphicsOptions textGraphicsOptions = new TextGraphicsOptions(true);
SolidBrush<Rgba32> brushYellow = new SolidBrush<Rgba32>(Rgba32.Yellow);
FontCollection fonts = new FontCollection();
fonts.Install(fontLocation);
Font font = fonts.CreateFont("Liberation Mono", PngFontHeight, FontStyle.Regular);
gif = new Image<Rgba32>(400, 400);
for (int i = 0; i < 10;++i)
{
img = new Image<Rgba32>(400, 400);
img.Mutate(x => x.Fill(Rgba32.Black));
img.Mutate(x => x.DrawText(textGraphicsOptions, i.ToString(), font, brushYellow, new PointF(1,1)));
gif.Frames.AddFrame(img.Frames[0]);
using (FileStream fs = File.Create(Path.Join(Program.workingDirectory, string.Format("Test-{0}.gif", i))))
{
img.SaveAsGif(fs);
}
img.Dispose();
}
using (FileStream fs = File.Create(Path.Join(Program.workingDirectory, "Test.gif")))
{
gif.SaveAsGif(fs);
}
}
如果我将其编码为加载每个individual physical file using this code,则它会按预期制作动画gif。
我只想在内存中创建动画gif。
答案 0 :(得分:2)
创建Image<>
...
gif = new Image<Rgba32>(400, 400);
... gif.Frames[0]
是一个“透明黑色”帧(每个像素的RGBA值为#00000000
)。您在for
循环中创建的其他框架,并添加......
gif.Frames.AddFrame(img.Frames[0]);
...从gif.Frames[1]
到gif.Frames[10]
,总共11帧。
GIF编码器使用GifColorTableMode
来确定是为每个帧生成颜色表还是为所有帧使用第一帧的颜色表。默认值GifColorTableMode.Global
加上第一个透明帧的组合将导致11帧.gif
文件只有一种颜色,即相同的“透明黑色”。这就是为什么您的黄色文本没有出现并且每个帧看起来都相同的原因。
要解决此问题,在保存文件之前,需要先删除该初始透明框架,以免影响颜色表的计算,并且因为它不是动画的一部分,所以...
gif.Frames.RemoveFrame(0);
您可能还希望更改为GifColorTableMode.Local
,因此您的.gif
文件包含反映所有渲染颜色的颜色表...
gif.MetaData.GetFormatMetaData(GifFormat.Instance).ColorTableMode = GifColorTableMode.Local;
...尽管您的10帧使用几乎相同的颜色集,所以如果文件大小比颜色表示更重要,则可以不考虑该属性。使用GifColorTableMode.Global
生成400×400动画会生成 9,835字节文件,而GifColorTableMode.Local
会生成 16,703字节文件; 70%,但我无法分辨两者之间的区别。
顺便说一句,自从我一路走来就发现了这一点,如果您想更改动画帧的持续时间,可以使用另一种GetFormatMetaData()
方法,类似于上面显示的方法...
GifFrameMetaData frameMetaData = img.MetaData.GetFormatMetaData(GifFormat.Instance);
frameMetaData.FrameDelay = 100;// 1 second