Bitmap.GetPixel 只为 R、G 和 B 返回 0

Bitmap.GetPixel only returning 0s for R, G and B

我正在使用 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,因此您的代码实际上工作正常。

而且大多数像素也有0alpha,所以它们是透明的。有些是 semi-transparent、anti-aliased 像素,有些是完全不透明的。

透明或 semi-transprent 像素的地方,背景色会透出来。

如果您想识别真正的 non-transparent 黑色像素,您还需要测试 alpha 通道。

这是一个函数,它将创建像素颜色和给定背景颜色的复合颜色..:[=​​15=]

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