Image Editing in C# – Greyscale

I’m in the process of writing some code to detect the stars in astromical images. One of the filters I need to apply to an image is to convert it to greyscale.

Conversion to greyscale is relatively straightforward – The red, green and blue values of a pixel all need to be set to the same value.

There is one caveat, and that is that our eyes are sensitive to different colors. This means that color images tend to have lots of blue and red when compared to green.

A typical formula to use is:
whitevalue = (red * .30) + (green * .59) + (blue * .11)

Note that in the above formula, the three decimal values add to 1.00. This means that white in the image is preserved and the range of 0-255 is not exceeded.

Here is some C# code to convert an image to greyscale. It takes a Bitmap type and returns a Bitmap type. It uses unsafe code for speed so you will need to compile with the allow unsafe code option.

public class imageFilters
    public static Bitmap greyScale(Bitmap oBitmap)
        BitmapData bmData = oBitmap.LockBits(new Rectangle(0, 0, oBitmap.Width,
            oBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        int stride = bmData.Stride;
        System.IntPtr Scan0 = bmData.Scan0;
            byte* ptr = (byte*)(void*)Scan0;
            int iRowEnd = stride - (oBitmap.Width * 3);
            for (int y = 0; y < oBitmap.Height; ++y)
                for (int x = 0; x < oBitmap.Width; ++x)
                    //GDI returns BGR rather than RGB
                    //Hence ptr[0] is Blue NOT Red
                    ptr[0] = ptr[1] = ptr[2] =
                        (byte)((.30 * ptr[2]) + (.59 * ptr[1]) + (.11 * ptr[0]));
                    ptr += 3;
                ptr += iRowEnd;
        return oBitmap;


Posted in C# Tips

Leave a Reply
