我想在代码和点播中将32位RGBA Image对象(最初是32位PNG)转换为32位灰度对象。
我已经在这里提出了read个other个问题,以及很多在线文章。我已经尝试过使用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}
});
正如我所读到的,这是一个非常标准的NTSC加权矩阵。然后我和Graphics.DrawImage
一起使用它,但正如我所说,部分透明像素仍然是彩色的。我应该指出这是通过WinForms PictureBox
在白色背景上显示Image对象。它可能只是PictureBox绘制图像和处理透明部分的方式吗?背景颜色不会影响它(颜色的色调肯定来自原始图像),但也许PictureBox没有正确地重绘透明像素?
我见过一些使用FormatConvertedBitmap和OpacityMask的方法。我没有尝试过,主要是因为我真的不想导入PresentationCore.dll(更不用说这意味着它不适用于.NET 2.0有限的应用程序)。当然基本的System.Drawing。*东西可以做这个简单的程序吗?或者不是?
答案 0 :(得分:5)
您是否有机会使用ColorMatrix将图像绘制到自身上?那当然不会起作用(因为如果你在绿色像素上画一些半透明灰色的东西,一些绿色会透过)。您需要将其绘制到仅包含透明像素的新空白位图上。
答案 1 :(得分:4)
感谢danbystrom空闲的好奇心,我确实在原版上重绘。对于任何感兴趣的人,这是我使用的更正方法:
using System.Drawing;
using System.Drawing.Imaging;
public Image ConvertToGrayscale(Image image)
{
Image grayscaleImage = new Bitmap(image.Width, image.Height, image.PixelFormat);
// Create the ImageAttributes object and apply the ColorMatrix
ImageAttributes attributes = new System.Drawing.Imaging.ImageAttributes();
ColorMatrix grayscaleMatrix = new 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}
});
attributes.SetColorMatrix(grayscaleMatrix);
// Use a new Graphics object from the new image.
using (Graphics g = Graphics.FromImage(grayscaleImage))
{
// Draw the original image using the ImageAttributes created above.
g.DrawImage(image,
new Rectangle(0, 0, grayscaleImage.Width, grayscaleImage.Height),
0, 0, grayscaleImage.Width, grayscaleImage.Height,
GraphicsUnit.Pixel,
attributes);
}
return grayscaleImage;
}
答案 2 :(得分:0)
如果您将图像转换为TGA,一种未压缩的imaeg格式,您可以使用“RubyPixels”直接编辑像素数据,随心所欲。然后,您可以将其转换回PNG。
我建议使用ImageMagick进行转换,同样来自ruby。