C# Drawing.Imaging dropping GIF frames if they are identical -
i need load gif animations , convert them frame frame bitmaps. that, extracting gif file frame frame using drawing.imaging library , casting each frame bitmap.
everything works fine except times when consecutive frames same, when there no pixel difference. library seems dropping such frames.
i came conslusion simple test. have created animation of circle growing , shrinking pause between moment last circle dissapears , new 1 not yet shown. when play animation consisting of extracted bitmaps pause not present. if compare gifs of same frame-length different amounts of identical frames, returned totalframescount value different. have observed webbrowsers display identical consecutive frames correctly.
public void drawgif(image img) { framedimension dimension = new framedimension(img.framedimensionslist[0]); int framecounttotal = img.getframecount(dimension); (int framecount = 0; framecount < framecounttotal; framecount++) { img.selectactiveframe(dimension, framecount); bitmap bmp = new bitmap(img); //cast image type bitmap (int = 0; < 16; i++) { (int j = 0; j < 16; j++) { color color = bmp.getpixel(i, j); drawpixel(i, j, 0, color.r, color.g, color.b); } } - does encountered such problem?
- as pretty new c# - there way modify .net lib ?
- maybe there solution problem not aware of, not involve changing library?
updated code - result same
public void drawgif(img) { int framecounttotal = img.getframecount(framedimension.time); (int framecount = 0; framecount < framecounttotal; framecount++) { img.selectactiveframe(framedimension.time, framecount); bitmap bmp = new bitmap(img); (int = 0; < 16; i++) { (int j = 0; j < 16; j++) { color color = bmp.getpixel(i, j); drawpixel(i, j, 0, color.r, color.g, color.b); }
the image not saving duplicate frames, have take time of each frame account. here sample code based on this book in windows programming on how frames , correct duration. example:
public class gif { public static list<frame> loadanimatedgif(string path) { //if path not found, should throw io exception if (!file.exists(path)) throw new ioexception("file not exist"); //load image var img = image.fromfile(path); //count frames var framecount = img.getframecount(framedimension.time); //if image not animated gif, should throw //argument exception if (framecount <= 1) throw new argumentexception("image not animated"); //list hold frames var frames = new list<frame>(); //get times stored in gif //propertytagframedelay ((propid) 0x5100) comes 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 4bit duration chunk int (int = 0; < framecount; i++) { //convert 4 bit value integer var duration = bitconverter.toint32(times, 4*i); //add new frame our list of frames frames.add( new frame() { image = new bitmap(img), duration = duration }); //set write frame before save img.selectactiveframe(framedimension.time, i); } //dispose image when we're done img.dispose(); return frames; } } we need structure save bitmap , duration each frame
//class store each frame public class frame { public bitmap image { get; set; } public int duration { get; set;} } the code load bitmap, check whether multi-frame animated gif. loops though frames construct list of separate frame objects hold bitmap , duration of each frame. simple use:
var framelist = gif.loadanimatedgif ("a.gif"); var = 0; foreach(var frame in framelist) frame.image.save ("frame_" + i++ + ".png");
Comments
Post a Comment