2016-07-14 2 views
3

Я хотел создать анимированное изображение gif из нескольких изображений с помощью C#, поэтому я использовал ниже решение github для этого.Сжимать размер анимированного gif-изображения с помощью C#

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

он работает как шарм, но это создает GIF из размера 45 МБ. Если я проверю свой фактический размер изображения, то это всего лишь 11 МБ, всего 47 изображений. но как-то gif генерируется с большими размерами.

Теперь я хочу сжать размер изображения gif, который создается с помощью C#.

Так можно ли каким-либо образом сжать размер gif-изображения?

+0

сделать поиск Google о том, как создать почтовый файл в C# есть много рабочих примеров онлайн также форматировать ваш второй помощью правильно с '{}' – MethodMan

+1

Я не хочу создавать zip, я хочу сжать размер анимированного gif, который создается – User5590

+1

сделать поиск в Google о том, как сжать размер gif C#, тогда – MethodMan

ответ

0

Я знаю, что это старый вопрос, но решил, что я поделюсь этим решением.

Я столкнулся с той же проблемой и обнаружил, что каждый кадр должен содержать только различия в пикселях от предыдущего кадра. Я думал, что кодировщик сделает для меня изображение diff, но, по-видимому, это не так.

Поэтому перед добавлением каждого кадра я сравниваю его с предыдущим кадром, используя этот метод, который я написал. Затем я добавляю результирующее изображение, содержащее только измененные пиксели.

Вот где я его с помощью: 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; 
    } 
} 
Смежные вопросы