如何将32位RGBA图像转换为保留alpha的灰度

Sea*_*ley 0 .net c# image image-processing image-conversion

我想在代码和按需中将32位RGBA Image对象(最初是32位PNG)转换为32位灰度对应物.

我已经在这里阅读其他几个问题,以及很多在线文章.我已经尝试过使用ColorMatrix来做到这一点,但它似乎并没有很好地处理alpha.完全不透明灰度的像素完美无缺.任何部分透明的像素似乎都不能很好地转换,因为这些像素中仍然存在色彩.这足以引人注目.

我使用的ColorMatrix如下:

new System.Drawing.Imaging.ColorMatrix(new float[][]{
                    new float[] {0.299f, 0.299f, 0.299f, 0, 0},
                    new float[] {0.587f, 0.587f, 0.587f, 0, 0},
                    new float[] {0.114f, 0.114f, 0.114f, 0, 0},
                    new float[] {     0,      0,      0, 1, 0},
                    new float[] {     0,      0,      0, 0, 1}
                    });
Run Code Online (Sandbox Code Playgroud)

正如我所读到的,这是一个非常标准的NTSC加权矩阵.我随后使用它,Graphics.DrawImage但正如我所说,部分透明像素仍然是彩色的.我应该指出这是通过WinForms PictureBox在白色背景上显示Image对象.它可能只是PictureBox绘制图像和处理透明部分的方式吗?背景颜色不会影响它(颜色的色调肯定来自原始图像),但也许PictureBox没有正确地重绘透明像素?

我见过一些使用FormatConvertedBitmap和OpacityMask的方法.我没有尝试过,主要是因为我真的不想导入PresentationCore.dll(更不用说这意味着它不适用于.NET 2.0有限的应用程序).当然基本的System.Drawing.*东西可以做这个简单的程序吗?或不?

Dan*_*röm 5

您是否有机会使用ColorMatrix将图像绘制到自身上?那当然不会起作用(因为如果你在绿色像素上画一些半透明灰色的东西,一些绿色会透过).您需要将其绘制到仅包含透明像素的新的空位图上.