使用C#压缩动画gif图像大小 [英] Compress animated gif image size using c#
问题描述
我想使用c#从多个图像创建动画gif图像,所以我在github解决方案下使用了此方法。
I wanted to create animated gif image from several images using c#, so i have used below github solution to do so.
https://github.com/DataDink/Bumpkit
我正在使用以下代码要做到这一点
I am using below code to do it
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);
}
它的工作原理很像魅力,但它创建的gif大小为45 MB 。如果我检查我的实际图像大小,则总共11张图像只有11MB。
it is working like a charm, but it is creating gif of size 45 MB. If i check my actual image size , then it is only 11MB with total 47 images. but somehow gif is generating with big size.
现在,我想压缩使用c#创建的gif图像的大小。
Now i want to compress the size of gif image which is being created using c#.
那么有什么办法可以压缩gif图像的大小?
So is there any way i can compress the size of gif image?
推荐答案
我知道这是一个
我遇到了同样的问题,发现每个帧只应包含与前一帧的像素差异。我以为编码器会帮我做图像比较,但是显然不行。
I ran into the same issue and found that each frame should contain only the differences in pixels from the previous frame. I thought that the encoder would do the image diff for me, but apparently it doesn't.
因此,在添加每帧之前,我将其与上一帧进行比较我写的方法。然后,我添加只包含更改后的像素的结果图像。
So before adding each frame, I compare it to the previous frame using this method I wrote. I then add the resulting image that contains only the changed pixels.
在这里使用它: 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;
}
}
这篇关于使用C#压缩动画gif图像大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!