Oleg Sh
Oleg Sh

Reputation: 9013

Check if image is monochromatic

I need to have a quick way to check whether image of monochromatic or not. I mean I need to verify that the image contains just a single color (black, white, red square...) instead of containing multiple colors.

Of course, I can compare all pixels of image with first, but it can be slow. Any another way to check it?

Upvotes: 1

Views: 664

Answers (2)

Mitch
Mitch

Reputation: 22271

It depends on your definition of slow. I am finding that it takes about 12 ms to scan a 1MP image if all pixels need to be evaluated, and significantly shorter (nanoseconds in most cases, since the first and second pixels are different) on a random sampling of images.

Test code (Core i5 on W8.1 x64, compiled with /unsafe /platform:x64 on .Net 4.5):

private unsafe bool CheckBitmapIsMonotonic(Bitmap newBitmap)
{
    var data = newBitmap.LockBits(new Rectangle(Point.Empty, newBitmap.Size),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    try
    {
        byte* pixelData = (byte*)data.Scan0.ToPointer();
        uint firstPixelData = *((uint*)pixelData);

        for (int row = 0; row < data.Height; row++)
        {
            uint* cRowPointer = (uint*)(pixelData + data.Stride * row);

            for (int column = 0; column < data.Width; column++)
            {
                var rgbPixelValue = cRowPointer[column];

                if (firstPixelData != rgbPixelValue)
                {
                    return false;
                }
            }
        }

        return true;
    }
    finally
    {
        newBitmap.UnlockBits(data);
    }
}

This is just a first pass. You may be able to squeeze some extra performance by moving to ulong rather than uint and compare two pixels at once, and if you can avoid the conversion to ARGB, all the better.

Upvotes: 3

Timo D
Timo D

Reputation: 1803

This highly depends on the image formats you would like to support (PNG, BMP, etc).

For instance, if the image uses a color palette (some types of PNG do), you could check if the palette has only one color entry. (see System.Drawing.Image.Palette).

But in general, you will probably have to check every pixel to make sure.

Upvotes: 1

Related Questions