我正在使用Image.FromFile
在控制台应用程序中加载图像。
之后,我将其强制转换为Bitmap
,以便能够使用Bitmap.GetPixel()
方法。
令人惊讶的是,当循环遍历所有像素时,我从GetPixel
得到的所有结果对于R,G,B都是0,0,0。
为确保从文件中良好读取图像,我添加了对System.Windows.Forms
的引用,并将图像加载到PictureBox
内以查看结果,并且图像清晰可见。
原始图片:
这是我加载图像并将其显示到PictureBox
中的方式:
Bitmap img = (Bitmap)Image.FromFile("image.png");
PictureBox pb = new PictureBox
{
Image = img
};
Form frm = new Form
{
Controls = { pb }
};
frm.ShowDialog();
哪个按原样显示图像:
然后,我得到像这样的像素:
byte[] input = new byte[784];
for (int x = 0; x < 28; x++)
{
for (int y = 0; y < 28; y++)
{
Color color = img.GetPixel(x, y);
byte r = color.R;
byte g = color.G;
byte b = color.B;
Console.Write($"{color.R},{color.G},{color.B}|||");
input[x * 28 + y] = (byte)((((r + g + b) / 3)));
}
Console.WriteLine();
}
请注意,图像尺寸为28x28px,我尝试了其他图像,但结果相同。
自从我以前使用该方法以来,我希望结果显示真实的色彩值,并且效果很好,但是现在打印到控制台的所有结果都是零,这让我很难理解。
由于PictureBox
显示的是真实的图像表示,因此我尝试从PictureBox.Image
获取像素,例如:
Color color = ((Bitmap)pb.Image).GetPixel(x, y);
这也不起作用,结果返回为零。
这可能是什么原因以及如何解决?
答案 0 :(得分:1)
图像中所有像素的所有颜色通道都是 0
,因此您的代码实际上可以正常工作。
并且大多数像素的alpha
也为0
,因此它们是透明的。有些是半透明的抗锯齿像素,有些是完全不透明的。
在透明或半透明像素的地方,背景色会发光。
如果要识别真正的非透明黑色像素,还需要测试alpha通道。
这是一个将创建像素颜色和给定背景颜色的复合颜色的函数。
Color Composite(Color color, Color backcolor)
{
byte r = (byte)(((255 - color.A) * backcolor.R + color.R * color.A) / 256);
byte g = (byte)(((255 - color.A) * backcolor.G + color.G * color.A) / 256);
byte b = (byte)(((255 - color.A) * backcolor.B + color.B * color.A) / 256);
Color c2 = Color.FromArgb(255, r, g, b);
return c2;
}
如果您想要一个像素的亮度,则可以创建其颜色与白色的合成。但是,鉴于您拥有的图像,您也可以直接使用color.A
。