C#Drawing.Imaging删除GIF帧,如果它们是相同的

我需要加载GIF动画并将它们逐帧转换为位图。 为此,我使用Drawing.Imaging库逐帧提取我的GIF文件,然后将每个帧转换为位图。

除了没有像素差异时连续帧相同的时候,一切都可以正常工作。 图书馆似乎正在放弃这样的框架。

我通过一个简单的测试来了这个混淆。 我创建了一个圆圈的动画,在最后一个圆圈消失和新的圆圈尚未显示的那一刻之间停顿一段时间后,这个圆圈正在增长并缩小。 当我播放由我提取的位图组成的动画时,暂停不存在。 如果我比较相同帧长度但不同数量的相同帧的GIF,返回的totalframescount值是不同的。 我还观察到web浏览器正确显示相同的连续帧。

  public void DrawGif(Image img)
    {

        FrameDimension dimension = new FrameDimension(img.FrameDimensionsList[0]);
        int frameCountTotal = img.GetFrameCount(dimension);   

        for (int framecount = 0; framecount < frameCountTotal; framecount++)
        {
            img.SelectActiveFrame(dimension, framecount);  

            Bitmap bmp = new Bitmap(img);  //cast Image type to Bitmap

                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 16; j++)
                    {
                        Color color = bmp.GetPixel(i, j);
                        DrawPixel(i, j, 0, color.R, color.G, color.B);

                    }
                }
  • 有人遇到过这样的问题吗?
  • 由于我对C#很新颖,有没有办法修改.NET lib?
  • 也许有一个解决方案,我不知道的问题,这不涉及改变图书馆?
  • 更新的代码 - 结果是一样的

     public void DrawGif(img)
         {
          int frameCountTotal = img.GetFrameCount(FrameDimension.Time);
           for (int framecount = 0; framecount < frameCountTotal; framecount++)
                {
        img.SelectActiveFrame(FrameDimension.Time, framecount); 
         Bitmap bmp = new Bitmap(img);
    
        for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 16; j++)
                    {
                            Color color = bmp.GetPixel(i, j);
                            DrawPixel(i, j, 0, color.R, color.G, color.B);
    
                    }
    

    Image不保存重复帧,因此您必须考虑每个帧的时间。 以下是Windows编程中基于本书的一些示例代码,了解如何获取所有帧和正确的持续时间。 一个例子:

    public class Gif
    {
        public static List<Frame> LoadAnimatedGif(string path)
        {
            //If path is not found, we should throw an IO exception
            if (!File.Exists(path))
                throw new IOException("File does not exist");
    
            //Load the image
            var img = Image.FromFile(path);
    
            //Count the frames
            var frameCount = img.GetFrameCount(FrameDimension.Time);
    
            //If the image is not an animated gif, we should throw an
            //argument exception
            if (frameCount <= 1)
                throw new ArgumentException("Image is not animated");
    
            //List that will hold all the frames
            var frames = new List<Frame>();
    
            //Get the times stored in the gif
            //PropertyTagFrameDelay ((PROPID) 0x5100) comes from gdiplusimaging.h
            //More info on http://msdn.microsoft.com/en-us/library/windows/desktop/ms534416(v=vs.85).aspx
            var times = img.GetPropertyItem(0x5100).Value;
    
            //Convert the 4bit duration chunk into an int
    
            for (int i = 0; i < frameCount; i++)
            {
                //convert 4 bit value to integer
                var duration = BitConverter.ToInt32(times, 4*i);
    
                //Add a new frame to our list of frames
                frames.Add(
                    new Frame()
                    {
                        Image = new Bitmap(img),
                        Duration = duration
                    });
    
                //Set the write frame before we save it
                img.SelectActiveFrame(FrameDimension.Time, i);
    
    
            }
    
            //Dispose the image when we're done
            img.Dispose();
    
            return frames;
        }
    }
    

    我们需要一个结构来保存每个Frame的Bitmap和持续时间

    //Class to store each frame
    public class Frame 
    { 
        public Bitmap Image { get; set; } 
        public int Duration { get; set;} 
    }
    

    该代码将加载一个Bitmap ,检查它是否是一个多帧动画GIF 。 然后它循环遍历所有的帧来构建一个单独的Frame对象列表,这些对象包含每个帧的位图和持续时间。 简单使用:

    var frameList = Gif.LoadAnimatedGif ("a.gif");
    
    var i = 0;
    foreach(var frame in frameList)
        frame.Image.Save ("frame_" + i++ + ".png");
    
    链接地址: http://www.djcxy.com/p/84137.html

    上一篇: C# Drawing.Imaging dropping GIF frames if they are identical

    下一篇: How to create a title that will not appear in the toctree with Sphinx