Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert BitmapImage to grayscale, and keep alpha channel

I'm having an issue with converting a BitmapImage (WPF) to grayscale, whilst keeping the alpha channel. The source image is a PNG.

The MSDN article here works fine, but it removes the alpha channel.

Is there any quick and effective way of converting a BitmapImage to a grayscale?

like image 994
Alastair Pitts Avatar asked Sep 24 '09 06:09

Alastair Pitts


3 Answers

It really depends upon what your source PixelFormat is. Assuming your source is PixelFormats.Bgra32 and that you want to go to grayscale, you might consider using a target pixel format of PixelFormats.Gray16. However, Gray16 doesn't support alpha. It just has 65,535 graduations between black and white, inclusive.

You have a few options. One is to stay with Bgra32 and just set the blue, green and red channels to the same value. That way you can keep the alpha channel. This may be wasteful if you don't require an 8-bit alpha channel (for differing levels of alpha per pixel).

Another option is to use an indexed pixel format such as PixelFormats.Indexed8 and create a palette that contains the gray colours you need and alpha values. If you don't need to blend alpha, you could make the palette colour at position zero be completely transparent (an alpha of zero) and then progress solid black in index 1 through to white in 255.

like image 23
Drew Noakes Avatar answered Nov 18 '22 16:11

Drew Noakes


You should have a look at image transformation using matrices.

In particular, this article describes how to convert a bitmap to grayscale using a ColorMatrix. (It is written in VB.NET, but it should be easy enough to translate to C#).

I haven't tested if it works with the alpha channel, but I'd say it's worth a try, and it definitely is a quick and effective way of modifying bitmaps.

like image 113
bernhof Avatar answered Nov 18 '22 16:11

bernhof


if relying on API calls fails. You can always try the 'do it yourself' approach: Just get access to the RGBA bytes of the picture, and for every RGBA replace it with MMMA, where M = (R+G+B)/3;

If you want it more perfect, you should add weights to the contribution of the RGB components. I believe your eye is more receptive for green, and as such that value should weigh more.

like image 1
Toad Avatar answered Nov 18 '22 17:11

Toad