Bitmap.GetPixel возвращает только 0 для R, G и B - PullRequest
1 голос
/ 15 мая 2019

Я загружаю изображение в консольное приложение, используя Image.FromFile.
После этого я преобразую его в Bitmap, чтобы можно было использовать метод Bitmap.GetPixel().Удивительно, но при прохождении через все пиксели все, что я получаю от GetPixel, составляет 0,0,0 для R, G, B.

Чтобы убедиться, что изображение хорошо читается из файла, я добавил ссылку на 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();
}

Обратите внимание, что размер изображения составляет 28x28 пикселей, и я пробовал другие изображения, и я получил тот же результат.

То, что я ожидал, что результаты показывают реальные значения цвета, так как я использовал этот методраньше и все работало отлично, но теперь все результаты, выводимые на консоль, представляют собой нули, которые мне трудно понять.


Редактировать:

Поскольку PictureBox показывает реальное представление изображения, я попытался получить пиксели от PictureBox.Image, например:

Color color = ((Bitmap)pb.Image).GetPixel(x, y);

Это также не сработало, и результаты вернулись в нули.


Что может быть причиной этого и как это исправить?

1 Ответ

1 голос
/ 15 мая 2019

В вашем изображении все цветовые каналы всех пикселей равны 0, поэтому код на самом деле работает нормально.

И большинство пикселей также имеют alpha 0, поэтому они прозрачны . Некоторые из них являются полупрозрачными, сглаженными пикселями, а некоторые - полностью непрозрачными.

Там, где есть прозрачные или полупрозрачные пиксели, задний цвет будет просвечивать.

Если вы хотите распознать действительно непрозрачные черные пиксели, вам нужно также протестировать альфа-канал.

Вот функция, которая создаст составной цвет цвета пикселя и заданного цвета фона ..:

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 напрямую ..

...