使用c#压缩GIF动画图像大小

我想用c#从几个图像创建动画gif图像,所以我使用下面的github解决方案来做到这一点。

https://github.com/DataDink/Bumpkit

我正在使用下面的代码来做到这一点

using (var gif = File.OpenWrite(@"C:\IMG_TEST.gif")) using (var encoder = new GifEncoder(gif)) for (int i = 0, count = imageFilePaths.Length; i < count; i++) { Image image = Image.FromFile(imageFilePaths[i]); encoder.AddFrame(image,0,0); } 

它就像一个魅力,但它正在创建大小为45 MB的gif。 如果我检查我的实际图像大小,那么它只有11MB,总共47个图像。 但不知何故,gif正在产生大尺寸。

现在我想压缩使用c#创建的gif图像的大小。

那么有什么方法可以压缩gif图像的大小?

我知道这是一个老问题,但我想我会分享这个解决方案。

我遇到了同样的问题,发现每个帧应该只包含与前一帧相差的像素。 我认为编码器会为我做图像差异,但显然它没有。

所以在添加每个帧之前,我使用我编写的这个方法将它与前一帧进行比较。 然后我添加仅包含更改像素的结果图像。

这是我使用它的地方: https : //github.com/Jay-Rad/CleanShot/blob/master/CleanShot/Classes/GIFRecorder.cs

 public class ImageDiff { public static Bitmap GetDifference(Bitmap bitmap1, Bitmap bitmap2) { if (bitmap1.Height != bitmap2.Height || bitmap1.Width != bitmap2.Width) { throw new Exception("Bitmaps are not of equal dimensions."); } if (!Bitmap.IsAlphaPixelFormat(bitmap1.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap2.PixelFormat) || !Bitmap.IsCanonicalPixelFormat(bitmap1.PixelFormat) || !Bitmap.IsCanonicalPixelFormat(bitmap2.PixelFormat)) { throw new Exception("Bitmaps must be 32 bits per pixel and contain alpha channel."); } var newImage = new Bitmap(bitmap1.Width, bitmap1.Height); var bd1 = bitmap1.LockBits(new System.Drawing.Rectangle(0, 0, bitmap1.Width, bitmap1.Height), ImageLockMode.ReadOnly, bitmap1.PixelFormat); var bd2 = bitmap2.LockBits(new System.Drawing.Rectangle(0, 0, bitmap2.Width, bitmap2.Height), ImageLockMode.ReadOnly, bitmap2.PixelFormat); // Get the address of the first line. IntPtr ptr1 = bd1.Scan0; IntPtr ptr2 = bd2.Scan0; // Declare an array to hold the bytes of the bitmap. int bytes = Math.Abs(bd1.Stride) * bitmap1.Height; byte[] rgbValues1 = new byte[bytes]; byte[] rgbValues2 = new byte[bytes]; // Copy the RGBA values into the array. Marshal.Copy(ptr1, rgbValues1, 0, bytes); Marshal.Copy(ptr2, rgbValues2, 0, bytes); // Check RGBA value for each pixel. for (int counter = 0; counter < rgbValues1.Length - 4; counter += 4) { if (rgbValues1[counter] != rgbValues2[counter] || rgbValues1[counter + 1] != rgbValues2[counter + 1] || rgbValues1[counter + 2] != rgbValues2[counter + 2] || rgbValues1[counter + 3] != rgbValues2[counter + 3]) { // Change was found. var pixel = counter / 4; var row = (int)Math.Floor((double)pixel / bd1.Width); var column = pixel % bd1.Width; newImage.SetPixel(column, row, Color.FromArgb(rgbValues1[counter + 3], rgbValues1[counter + 2], rgbValues1[counter + 1], rgbValues1[counter])); } } bitmap1.UnlockBits(bd1); bitmap2.UnlockBits(bd2); return newImage; } }