10

I have a PNG image being sent from a DrawingView in Android to a WCF service. The image is sent as a 32-bit and it has transparent background. I want to replace the transparent colour (for lack of a better word) background with white. So far my code looks like this:

// Converting image to Bitmap object
Bitmap i = new Bitmap(new MemoryStream(Convert.FromBase64String(image)));
// The image that is send from the tablet is 1280x692
// So we need to crop it
Rectangle cropRect = new Rectangle(640, 0, 640, 692);
//HERE
Bitmap target = i.Clone(cropRect, i.PixelFormat);
target.Save(string.Format("c:\\images\\{0}.png", randomFileName()),
System.Drawing.Imaging.ImageFormat.Png);

The above works fine, except the images have transparent background. I noticed that in Paint.NET you can simply set the PNG format to 8-bit and it sets the background to white. However, when I tried using:

System.Drawing.Imaging.PixelFormat.Format8bppIndexed

all I got was a completely black picture.

Q: How to replace the transparent background with white in a png?

PS. The image is in Gray Scale.

Dawid O
  • 6,091
  • 7
  • 28
  • 36
  • Is there a reason why you tried the indexed format? Have you tried any of the 24 bpp formats? – Nico Schertler Dec 05 '14 at 15:01
  • You should be able to create a white Bitmap and draw the Image onto it, then save as whatever.. – TaW Dec 05 '14 at 15:04
  • @NicoSchertler Hmm.. I tried most of them, I don't think all. Format24bppRgb gives the same result. – Dawid O Dec 05 '14 at 15:05
  • @TaW this was a correct answer. Undelete it, so I can mark it – Dawid O Dec 05 '14 at 15:16
  • OK, but I still fighting with one PNG I have, which doesn't work as I expect.. I'll update when I find the reason – TaW Dec 05 '14 at 15:20
  • OK, I give up, I can't reproduce with any other image, so I don't think there is any fault with the answer after all. – TaW Dec 05 '14 at 15:31

1 Answers1

26

This will draw onto a given color:

Bitmap Transparent2Color(Bitmap bmp1, Color target)
{
    Bitmap bmp2 = new Bitmap(bmp1.Width, bmp1.Height);
    Rectangle rect = new Rectangle(Point.Empty, bmp1.Size);
    using (Graphics G = Graphics.FromImage(bmp2) )
    {
        G.Clear(target);
        G.DrawImageUnscaledAndClipped(bmp1, rect);
    }
    return bmp2;
}

This makes use of the G.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;, which is the default. It blends the drawn image with the background according to the alpha channel of the drawn image.

TaW
  • 53,122
  • 8
  • 69
  • 111