Как проверить, является ли пиксель белым в байтовом массиве? - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь обрезать Bitmap на основе белых пикселей.Я хотел бы сделать это эффективно, поэтому я избегаю использования .GetPixel

Я реализую отмеченный правильный ответ на этот вопрос .В ответ они определяют, являются ли пиксели в байтовом массиве прозрачными.Я хотел бы определить, являются ли пиксели белыми вместо этого с порогом (поэтому, если он меньше белого, чем порог, то foundPixel=true;.

Я извлек соответствующий код здесь:

static Bitmap TrimBitmap(Bitmap source)
{
BitmapData data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] buffer = new byte[data.Height * data.Stride];
Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
...
}

Обнаружение альфа-пиксельного кода ( Вот что мне нужно, чтобы помочь с ):

byte alpha = buffer[y * data.Stride + 4 * x + 3];

if (alpha != 0)
{
    foundPixel = true;
    break;
}

1 Ответ

0 голосов
/ 25 июля 2019

Поскольку вы запрашиваете растровые данные как Format32bppArgb со своим кодом, результирующие байты всегда будут в 4-байтовом формате ARGB.Поскольку это относится к порядку байтов с прямым порядком байтов Uint32, фактические цветовые компоненты в байтах имеют порядок B, G, R, A.

Чтобы проверить на белый, вам просто нужно проверить B, G, R байт, а не A one:

BitmapData data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] buffer = new byte[data.Height * data.Stride];
Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
Int32 stride = data.Stride;
source.UnlockBits(data);
Int32 height = source.Height;

Int32 lineStart = 0;
for (Int32 y = 0; y < height; ++y)
{
    Int32 offset = lineStart;
    for (Int32 x = 0; x < stride; x += 4)
    {
        byte blue  = buffer[offset + 0];
        byte green = buffer[offset + 1];
        byte red   = buffer[offset + 2];
        //byte alpha = buffer[offset + 3];
        if (blue > threshold && green > threshold && red > threshold)
        {
            // is white pixel.
        }
        offset += 4;
    }
    lineStart += stride;
}

threshold здесь это значение, близкое к 255, которое определяет, какое значение на всех трех цветовых компонентах необходимо, чтобы пиксель был как можно ближе к белому.

Конечно, это еще не настоящий код обрезки, но вы должны быть в состоянии понять его оттуда.Если вам интересно, я разместил алгоритм обрезки здесь , но он работает с одним конкретным значением, а не с порогом.Используя приведенный выше код, вы можете адаптировать его под свои нужды.

...