Check If Image Is Colored Or Not

.net, c#, gdi+, image, pixelformat

Solution

You can improve this by avoiding Color.FromArgb, and iterating over bytes instead of ints, but I thought this would be more readable for you, and easier to understand as an approach.

The general idea is draw the image into a bitmap of known format (32bpp ARGB), and then check whether that bitmap contains any colors.

Locking the bitmap's bits allows you to iterate through it's color-data many times faster than using GetPixel, using unsafe code.

If a pixel's alpha is 0, then it is obviously GrayScale, because alpha 0 means it's completely opaque. Other than that - if R = G = B, then it is gray (and if they = 255, it is black).

private static unsafe bool IsGrayScale(Image image)
{
    using (var bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb))
    {
        using (var g = Graphics.FromImage(bmp))
        {
            g.DrawImage(image, 0, 0);
        }

        var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);

        var pt = (int*)data.Scan0;
        var res = true;

        for (var i = 0; i < data.Height * data.Width; i++)
        {
            var color = Color.FromArgb(pt[i]);

            if (color.A != 0 && (color.R != color.G || color.G != color.B))
            {
                res = false;
                break;
            }
        }

        bmp.UnlockBits(data);

        return res;
    }
}

Problem

I'm trying to figure out whether an image is colored or not. On this StackOverflow question, there's a reply that says that I should check the `PixelFormat` enum of the `Image`. Unfortunately, the reply isn't very clear to me. Is it safe to check whether the `image.PixelFormat` is different from `PixelFormat.Format16bppGrayScale` to consider that it is a colored image? What about the other values of the enumeration? The MSDN documentation isn't very clear...

Original source

Related problems