Advertisement
is_a_cdr

Save animated gif using System.Drawing

Jan 26th, 2015
541
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.91 KB | None | 0 0
  1. // Gdi+ constants absent from System.Drawing.
  2. const int PropertyTagFrameDelay = 0x5100;
  3. const int PropertyTagLoopCount = 0x5101;
  4. const short PropertyTagTypeLong = 4;
  5. const short PropertyTagTypeShort = 3;
  6.  
  7. // ...
  8.  
  9. var gifEncoder = GetEncoder(ImageFormat.Gif);
  10. // Params of the first frame.
  11. var encoderParams1 = new EncoderParameters(1);
  12. encoderParams1.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
  13. // Params of other frames.
  14. var encoderParamsN = new EncoderParameters(1);
  15. encoderParamsN.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionTime);            
  16. // Params for the finalizing call.
  17. var encoderParamsFlush = new EncoderParameters(1);
  18. encoderParamsFlush.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.Flush);
  19.  
  20. // PropertyItem for the frame delay (apparently, no other way to create a fresh instance).
  21. var frameDelay = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem));
  22. frameDelay.Id = PropertyTagFrameDelay;
  23. frameDelay.Type = PropertyTagTypeLong;
  24. // Length of the value in bytes.
  25. frameDelay.Len = Bitmaps.Count * 4;
  26. // The value is an array of 4-byte entries: one per frame.
  27. // Every entry is the frame delay in 1/100-s of a second, in little endian.
  28. frameDelay.Value = new byte[Bitmaps.Count * UintBytes];
  29. // E.g., here, we're setting the delay of every frame to 1 second.
  30. var frameDelayBytes = BitConverter.GetBytes((uint)100);
  31. for (int j = 0; j < Bitmaps.Count; ++j)
  32.     Array.Copy(frameDelayBytes, 0, frameDelay.Value, j * UintBytes, UintBytes);
  33.  
  34. // PropertyItem for the number of animation loops.
  35. var loopPropertyItem = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem));
  36. loopPropertyItem.Id = PropertyTagLoopCount;
  37. loopPropertyItem.Type = PropertyTagTypeShort;
  38. loopPropertyItem.Len = 1;
  39. // 0 means to animate forever.
  40. loopPropertyItem.Value = BitConverter.GetBytes((ushort)0);
  41.  
  42. using (var stream = new FileStream("animation.gif", FileMode.Create))
  43. {
  44.     bool first = true;
  45.     Bitmap firstBitmap = null;
  46.     // Bitmaps is a collection of Bitmap instances that'll become gif frames.
  47.     foreach (var bitmap in Bitmaps)
  48.     {
  49.         if (first)
  50.         {
  51.             firstBitmap = bitmap;
  52.             firstBitmap.SetPropertyItem(frameDelay);
  53.             firstBitmap.SetPropertyItem(loopPropertyItem);
  54.             firstBitmap.Save(stream, gifEncoder, encoderParams1);
  55.             first = false;
  56.         }
  57.         else
  58.         {
  59.             firstBitmap.SaveAdd(bitmap, encoderParamsN);
  60.         }
  61.     }
  62.     firstBitmap.SaveAdd(encoderParamsFlush);
  63. }
  64.  
  65. // ...
  66.  
  67. private ImageCodecInfo GetEncoder(ImageFormat format)
  68. {
  69.  
  70.     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
  71.     foreach (ImageCodecInfo codec in codecs)
  72.     {
  73.         if (codec.FormatID == format.Guid)
  74.         {
  75.             return codec;
  76.         }
  77.     }
  78.     return null;
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement