How to test whether pixel is white in byte array?

丶灬走出姿态 提交于 2021-01-29 05:11:56

问题


I'm trying to trim a Bitmap based on white pixels. I'd like to do it efficiently, so I'm avoiding using .GetPixel

I'm implementing the marked-correct answer from this question. In the answer, they detect whether pixels in a byte array are transparent. I would like to detect whether the pixels are white instead, with a threshold (so if it is less white than a threshold then foundPixel=true;.

I've extracted the relevant code here:

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);
...
}

Detecting the alpha pixel code (this is what I need help with):

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

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

回答1:


Since you're requesting the bitmap data as Format32bppArgb with your code, the resulting bytes will always be in 4-byte ARGB format. Since this refers to a little-endian Uint32, the actual colour components in the bytes are in order B, G, R, A.

To check for white, you just need to check the B, G, R bytes rather than the 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 width = source.Width;

Int32 lineStart = 0;
for (Int32 y = 0; y < height; ++y)
{
    Int32 offset = lineStart;
    for (Int32 x = 0; x < width; ++x)
    {
        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 here is a value close to 255 that determines what value on all three colour components is needed for the pixel to be seen as close enough to white.

Of course, that's not actual cropping code yet, but you should be able to figure it out from there. If you're interested, I posted a crop algorithm here, but that one works on one specific value, not on a threshold. Using the above code you could adapt it to your needs.



来源:https://stackoverflow.com/questions/56599489/how-to-test-whether-pixel-is-white-in-byte-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!