1
votes

I see many questions about how to load a PNG with an alpha channel and display it, but none about how to load a PNG that has an alpha channel but ignore the alpha channel, revealing the underlying RGB data.

I've tried simply removing all the data from the alpha channel, but I just get black pixels instead of the color data I want. It seems that from the moment I create the Bitmap object, it does not contain any color information in pixels where alpha is 0, though I assure you that information is physically there in the PNG.

To be clear, if my image contains a pixel with these values: (R:255 G:128 B:128 A:0) I need that pixel to be (R:255 G:128 B:128 A:255), not (R:0 G:0 B:0 A:255).

Thanks

EDIT: The previous information is incorrect. The bitmap contains all the information when using:

Bitmap myImage = Bitmap("filename.png");

What i was doing wrong is afterwards using:

Bitmap otherImage = Bitmap(myImage);

It seems that this is what nullifies the data I needed. Instead, I am now using

Bitmap otherImage = (Bitmap)(myImage.Clone());

and afterwards manually setting the alpha channel to opaque using lockbits. I hope this may be useful to someone in the future.

1

1 Answers

4
votes

Try this extension method:

    public static void SetAlpha(this Bitmap bmp, byte alpha)
    {
        if(bmp == null) throw new ArgumentNullException("bmp");

        var data = bmp.LockBits(
            new Rectangle(0, 0, bmp.Width, bmp.Height),
            System.Drawing.Imaging.ImageLockMode.ReadWrite,
            System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        var line = data.Scan0;
        var eof = line + data.Height * data.Stride;
        while(line != eof)
        {
            var pixelAlpha = line + 3;
            var eol = pixelAlpha + data.Width * 4;
            while(pixelAlpha != eol)
            {
                System.Runtime.InteropServices.Marshal.WriteByte(
                    pixelAlpha, alpha);
                pixelAlpha += 4;
            }
            line += data.Stride;
        }
        bmp.UnlockBits(data);
    }

Usage:

var pngImage = new Bitmap("filename.png");
pngImage.SetAlpha(255);