20 July 2018
Categories: Software Development
Posted in: C#, .NET, Image
Goals
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 not 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! ;)