Convert a color image to grayscale with C#

Goals

  • Convert a color image to grayscale
  • Avoid using native libraries (interoperability)

Convert a color image to grayscale with C#

This article will teach you how to convert a color image to grayscale using C# and .NET. For an explanation on grayscale conversion please visit: https://en.wikipedia.org/wiki/Grayscale

The following method will convert an RGB stream to grayscale:

public byte[] ConvertRGBToGrayscale(byte[] data)
{
    for (int i = 0; i < data.Length;) // Note that we are note incrementing variable 'i' here, because we do it in the body of the for loop.
    {
        if (i == data.Length - 1) break;

        var b = data[i];
        var g = data[i + 1];
        var r = data[i + 2];

        var monochrome = Convert.ToByte(r * 0.2125 + g * 0.7154 + b * 0.0721);

        data[i++] = monochrome;
        data[i++] = monochrome;
        data[i++] = monochrome;
    }

    return (byte[])data.Clone();
}

If your source data is ARGB, the following method will preserve the alpha channel:

public byte[] ConvertARGBToGrayscale(byte[] data)
{
    for (int i = 0; i < data.Length;)
    {
        var b = data[i];
        var g = data[i + 1];
        var r = data[i + 2];
        var a = data[i + 3];

        var monochrome = Convert.ToByte(r * 0.2125 + g * 0.7154 + b * 0.0721);

        data[i++] = monochrome;
        data[i++] = monochrome;
        data[i++] = monochrome;
        data[i++] = a;
    }

    return (byte[])data.Clone();
}

To obtain a byte stream representation of your image, in .NET Framework you can use the following conversion:

public Bitmap ToGrayscale(Bitmap image)
{
    byte[] result;

    switch (image.Format)
    {
        case Bitmap.BitmapFormat.ARGB:
            result = ConvertARGBToGrayscale(image.ToArray());
            break;
        case Bitmap.BitmapFormat.RGB:
            result = ConvertRGBToGrayscale(image.ToArray());
            break;
    }

    return new Bitmap(result, image.Width, image.Height, image.Format);
}

There are a several performance optimizations that can be applied to this code but even as it is it's quite fast and, most importantly, it's easily readable.

Happy Coding! ;)

comments powered by Disqus