Reputation: 26281
I can't believe this hasn't been asked yet, but...
How can I replace the transparent background of a GIF image to white, without breaking the animation?
I am way out of my field here, so I'm pretty much lost (I really don't know what to do).
This is what I tried without luck:
public byte[] RemoveTransparency(byte[] gifBytes)
{
using(MemoryStream gifStream = new MemoryStream(gifBytes))
using(Image gifImage = Image.FromStream(gifStream))
using(Image newImage = new Bitmap(gifImage.Width, gifImage.Height, PixelFormat.Format32bppPArgb))
using(MemoryStream newImageStream = new MemoryStream())
{
Color background = Color.White;
newImage.SetResolution(gifImage.HorizontalResolution, gifImage.VerticalResolution);
using (Graphics graphics = Graphics.FromImage(newImage))
{
graphics.Clear(background );
graphics.DrawImage(gifImage, 0, 0, gifImage.Width, gifImage.Height);
}
newImage.Save(newImageStream);
return newImageStream.ToArray();
}
}
Upvotes: 0
Views: 1270
Reputation: 316
You can use a bitmap.
using(var ms = new MemoryStream(gifBytes))
using(var b = new Bitmap(Image.FromStream(ms)))
{
for(var y = 0; y < b.Height; ++y)
for(var x = 0; x < b.Width; ++x)
if(b.GetPixel(x, y).A == 0) //Completely opaque
b.SetPixel(x, y, Color.White); //Sets white
}
//Note: b goes out of scope here and will be deleted eventually.
Do note that this algorithm is extremely slow on large images, a typical approach to get around this is to access the internal buffer directly which requires unsafe context. See MSDN Bitmap reference or this: https://msdn.microsoft.com/en-us/library/5ey6h79d(v=vs.110).aspx
If the bitmap breaks the animation, load each frame as described in the comments of your post and then write the final buffer back into main image memory. Comment if you want me to edit for this context.
Upvotes: 1