C # Drawing.Imaging discards GIFs if they are the same

I need to load GIF animations and convert them frame by frame into bitmaps. To do this, I extract my GIF file frame by frame using the Drawing.Imaging library and then custom-cast each frame into a bitmap image.

Everything works fine, except when consecutive frames are the same, when there is no difference in pixels. It seems that the library leaves such frames.

I came to this conclusion with a simple test. I created an animation of a circle that grows and contracts with a pause between the moment when the last circle disappears and a new one has not yet been shown. When I play an animation consisting of my extracted bitmaps, there is no pause. If I compare GIFs of the same frame length, but with different numbers of identical frames, the totalframescount return value is different. I also noticed that web browsers display the same consecutive frames correctly.

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); } } 
  • Has anyone encountered such a problem?
  • As I am pretty new to C # - is there a way to change .NET lib?
  • Perhaps there is a solution to my problem, which I do not know about, which is not related to changing the library?

Updated code - same result

  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); } 
0
c # gif animated-gif
source share
1 answer

Image does not save repeated frames, so you need to consider time . Here is sample code based on this book in Windows Programming on how to get all the frames and the correct duration. Example:

 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; } } 

We need a structure to save the bitmap and duration for each frame

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

The code will load Bitmap , check if it is a multi-frame animated GIF . He then iterates over all the frames to build a list of individual Frame objects that contain a bitmap and the duration of each frame. Simple use:

 var frameList = Gif.LoadAnimatedGif ("a.gif"); var i = 0; foreach(var frame in frameList) frame.Image.Save ("frame_" + i++ + ".png"); 
+1
source share

All Articles