将位图转换为灰度图,并保留alpha通道

时间:2022-12-08 00:22:01

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

我在将位图(WPF)转换为灰度时遇到了一个问题,同时保留了alpha通道。源图像是一个PNG。

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

这里的MSDN文章工作得很好,但是它删除了alpha通道。

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

有没有快速有效的方法将位图转换为灰度?

4 个解决方案

#1


2  

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#).

特别地,本文描述了如何使用ColorMatrix将位图转换为灰度图。(它是用VB写的。NET,但是它应该很容易翻译成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.

我还没有测试它是否与alpha通道一起工作,但是我认为它值得一试,而且它绝对是一种快速有效的修改位图的方法。

#2


2  

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.

这取决于你的源像素格式。假设源文件是像素格式。如果您想要使用灰度,可以考虑使用pixelformat . gray16的目标像素格式。然而,Gray16并不支持alpha。它有65,535个毕业典礼,在黑人和白人之间,包括在内。

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).

你有几个选择。一种是保留Bgra32并将蓝色、绿色和红色通道设置为相同的值。这样你就可以保持阿尔法通道。如果不需要8位的alpha通道(每个像素的alpha级别不同),这可能会造成浪费。

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.

另一种选择是使用索引像素格式,如像素格式。Indexed8并创建一个调色板,该调色板包含所需的灰色颜色和alpha值。如果不需要混合alpha,可以将位置为0的调色板颜色设置为完全透明(alpha值为0),然后将索引1中的纯黑色改为255中的白色。

#3


1  

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;

如果依赖API调用失败。你可以尝试“自己做”的方法:只需要访问图片的RGBA字节,每一个RGBA都用MMMA替换,其中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.

如果您希望它更完美,您应该为RGB组件的贡献添加权重。我相信你的眼睛更容易接受绿色,因此这个值应该更有分量。

#4


0  

While not exactly quick and easy, a ShaderEffect would do the job and perform quite well. I've done it myself, and it works great. This article references how to do it and has source associated. I've not used his source, so I can't vouch for it. If you run into problems, ask, and I may be able to post some of my code.

虽然不那么快速简单,但是阴影效果会很好地完成任务。我自己做过,效果很好。本文引用了如何进行此操作,并提供了与源相关的内容。我没有使用他的资料,所以我不能担保。如果您遇到问题,可以问我,我可能可以发布我的一些代码。

Not every day you get to use HLSL in your LOB app. :)

不是每天你都能在你的LOB应用中使用HLSL。

#1


2  

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#).

特别地,本文描述了如何使用ColorMatrix将位图转换为灰度图。(它是用VB写的。NET,但是它应该很容易翻译成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.

我还没有测试它是否与alpha通道一起工作,但是我认为它值得一试,而且它绝对是一种快速有效的修改位图的方法。

#2


2  

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.

这取决于你的源像素格式。假设源文件是像素格式。如果您想要使用灰度,可以考虑使用pixelformat . gray16的目标像素格式。然而,Gray16并不支持alpha。它有65,535个毕业典礼,在黑人和白人之间,包括在内。

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).

你有几个选择。一种是保留Bgra32并将蓝色、绿色和红色通道设置为相同的值。这样你就可以保持阿尔法通道。如果不需要8位的alpha通道(每个像素的alpha级别不同),这可能会造成浪费。

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.

另一种选择是使用索引像素格式,如像素格式。Indexed8并创建一个调色板,该调色板包含所需的灰色颜色和alpha值。如果不需要混合alpha,可以将位置为0的调色板颜色设置为完全透明(alpha值为0),然后将索引1中的纯黑色改为255中的白色。

#3


1  

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;

如果依赖API调用失败。你可以尝试“自己做”的方法:只需要访问图片的RGBA字节,每一个RGBA都用MMMA替换,其中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.

如果您希望它更完美,您应该为RGB组件的贡献添加权重。我相信你的眼睛更容易接受绿色,因此这个值应该更有分量。

#4


0  

While not exactly quick and easy, a ShaderEffect would do the job and perform quite well. I've done it myself, and it works great. This article references how to do it and has source associated. I've not used his source, so I can't vouch for it. If you run into problems, ask, and I may be able to post some of my code.

虽然不那么快速简单,但是阴影效果会很好地完成任务。我自己做过,效果很好。本文引用了如何进行此操作,并提供了与源相关的内容。我没有使用他的资料,所以我不能担保。如果您遇到问题,可以问我,我可能可以发布我的一些代码。

Not every day you get to use HLSL in your LOB app. :)

不是每天你都能在你的LOB应用中使用HLSL。