【问题标题】:imagesharp trying to make an animated gif that count from 0 to 9imagesharp 试图制作一个从 0 到 9 的动画 gif
【发布时间】:2019-06-27 09:29:45
【问题描述】:

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

【问题讨论】:

  • 从您的简短描述中,尚不清楚预期结果与实际结果是什么。 Test.gif 只是一个黑框吗?这 10 个 Test-{0}.gif 文件是“个人 gif”吗?如果是,它们有何“不同”?
  • @BACON 我更新了标题和描述

标签: c# .net-core animated-gif imagesharp


【解决方案1】:

当您创建 Image&lt;&gt;...

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% 更大,但我无法分辨它们之间的区别。

Related issue on GitHub

顺便说一句,由于我在此过程中发现了这一点,如果您想更改动画帧的持续时间,您可以使用类似于上面显示的另一种 GetFormatMetaData() 方法...

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

frameMetaData.FrameDelay = 100;// 1 second

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 2012-08-23
    相关资源
    最近更新 更多