imagesharp 试图制作一个从 0 到 9 的动画 gif

imagesharp trying to make an animated gif that count from 0 to 9

谁能告诉我为什么这会生成一个只有黑色的动画 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);
        }
    }

如果我对其进行编码以加载每个 它会按预期制作动画 gif。

我只想在内存中创建动画 gif。

当您创建 Image<>...

gif = new Image<Rgba32>(400, 400);

...gif.Frames[0] 是一个 "transparent black" 帧(每个像素的 RGBA 值为 #00000000)。您在 for 循环中创建的额外帧并添加...

gif.Frames.AddFrame(img.Frames[0]);

...通过gif.Frames[10]变为gif.Frames[1],共11帧。

GIF 编码器使用 GifColorTableMode 来决定是为每一帧生成颜色 table 还是为所有帧使用第一帧的颜色 table。默认值 GifColorTableMode.Global 加上第一个透明帧的组合导致 11 帧 .gif 文件只有一种颜色,即 "transparent black"。这就是为什么您的黄色文本没有出现并且每一帧看起来都一样。

要解决这个问题,在保存文件之前的某个时候,您需要删除初始透明帧,这样它就不会影响颜色 table 计算,而且因为它不是动画的一部分,无论如何.. .

gif.Frames.RemoveFrame(0);

您可能还想更改为 GifColorTableMode.Local,以便您的 .gif 文件包含颜色 tables 反映所有呈现的颜色...

gif.MetaData.GetFormatMetaData(GifFormat.Instance).ColorTableMode = GifColorTableMode.Local;

...尽管您的 10 帧每个都使用几乎相同的颜色集,所以如果文件大小比颜色表示更受关注,您可能会单独使用 属性。使用 GifColorTableMode.Global 生成 400 × 400 动画会生成 9,835 字节 文件,而 GifColorTableMode.Local 会生成 16,703 字节 文件; 70%大了但是我分不清它们的区别

Related issue on GitHub

顺便说一句,因为我一路上发现了这个,如果你想改变动画帧的持续时间,你可以使用另一种 GetFormatMetaData() 类似于上面显示的方法...

GifFrameMetaData frameMetaData = img.MetaData.GetFormatMetaData(GifFormat.Instance);

frameMetaData.FrameDelay = 100;// 1 second