Bitmap.GetPixel对于R,G和B仅返回0

时间:2019-05-15 08:11:59

标签: c# image bitmap console-application

我正在使用Image.FromFile在控制台应用程序中加载图像。
之后,我将其强制转换为Bitmap,以便能够使用Bitmap.GetPixel()方法。 令人惊讶的是,当循环遍历所有像素时,我从GetPixel得到的所有结果对于R,G,B都是0,0,0。

为确保从文件中良好读取图像,我添加了对System.Windows.Forms的引用,并将图像加载到PictureBox内以查看结果,并且图像清晰可见。

原始图片:

Original Image

这是我加载图像并将其显示到PictureBox中的方式:

Bitmap img = (Bitmap)Image.FromFile("image.png");

PictureBox pb = new PictureBox
{
    Image = img
};

Form frm = new Form
{
    Controls = { pb }
};

frm.ShowDialog();

哪个按原样显示图像:

Form shown after calling Form.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);

这也不起作用,结果返回为零。


这可能是什么原因以及如何解决?

1 个答案:

答案 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