简体   繁体   English

imagesharp尝试制作从0到9的动画gif

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

anyone could tell me why this generate a black only animated gif? 谁能告诉我为什么这会生成仅黑色的gif动画?

the code also output each in memory generated gif to show that they are different 代码还会在内存生成的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);
        }
    }

if I code it to load each individual physical file using this code it make the animated gif as expected. 如果我使用此代码对其进行编码以加载每个单独的物理文件,则会使gif动画达到预期效果。

I want to create the animated gif in memory only. 我只想在内存中创建动画gif。

When you create an Image<> ... 创建Image<> ...

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

... gif.Frames[0] is a "transparent black" frame (each pixel's RGBA value is #00000000 ). ... gif.Frames[0]是一个“透明的黑色”帧(每个像素的RGBA值为#00000000 )。 The additional frames you create in your for loop and add with... 您在for循环中创建的其他框架for并添加...

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

...become gif.Frames[1] through gif.Frames[10] , for a total of 11 frames. ...成为gif.Frames[1]gif.Frames[10] ,总共11帧。

The GIF encoder uses GifColorTableMode to decide if a color table is generated for each frame or the color table for the first frame is used for all frames. GIF编码器使用GifColorTableMode来确定是为每个帧生成颜色表还是为所有帧使用第一帧的颜色表。 The combination of the default value, GifColorTableMode.Global , plus that first transparent frame results in an 11-frame .gif file with only one color, that same "transparent black". 默认值GifColorTableMode.Global加上该第一个透明帧的组合将导致11帧.gif文件只有一种颜色,即相同的“透明黑色”。 This is why your yellow text doesn't appear and every frame looks the same. 这就是为什么您的黄色文本没有出现并且每个帧看起来都一样的原因。

To solve this, at some point before you save the file you need to remove that initial transparent frame so it doesn't influence color table calculations and because it's not part of your animation, anyways... 为了解决这个问题,在保存文件之前的某个时候,您需要删除该初始透明框架,以免影响颜色表的计算,并且因为它不是动画的一部分,所以无论如何...

gif.Frames.RemoveFrame(0);

You may also want to change to GifColorTableMode.Local so your .gif file contains color tables reflecting all of the colors rendered... 您可能还想更改为GifColorTableMode.Local以便您的.gif文件包含反映所有渲染颜色的颜色表...

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

...although your 10 frames each use almost the same set of colors so if file size is a greater concern than color representation you might leave that property alone. ...虽然您的10帧使用几乎相同的颜色集,所以如果文件大小比颜色表示更为重要,则可以不考虑该属性。 Generating your 400 × 400 animation with GifColorTableMode.Global produces a 9,835-byte file whereas GifColorTableMode.Local produces a 16,703-byte file; 使用GifColorTableMode.Global生成400×400动画会生成9,835字节的文件,而GifColorTableMode.Local会生成16,703字节的文件; 70% bigger but I can't tell the difference between them. 大70%,但我无法分辨两者之间的区别。

Related issue on GitHub GitHub上的相关问题

By the way, since I found this along the way, if you wanted to change the duration of the animated frames you would do so using another GetFormatMetaData() method similar to the one shown above... 顺便说一句,由于我一直都这样,所以如果您想更改动画帧的持续时间,可以使用另一种类似于上面所示的GetFormatMetaData()方法来进行。

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

frameMetaData.FrameDelay = 100;// 1 second

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM