public Bitmap GetGreyScale(Bitmap source, bool writingInWhite = false)
{
Bitmap dest = (Bitmap)source.Clone();
PixelFormat pxf = PixelFormat.Format24bppRgb;
Rectangle rect = new Rectangle(0, 0, dest.Width, dest.Height);
BitmapData bmpData = dest.LockBits(rect, ImageLockMode.ReadWrite, pxf);
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int numBytes = bmpData.Stride * dest.Height;
byte[] rgbValues = new byte[numBytes];
// Copy the RGB values into the array.
Marshal.Copy(ptr, rgbValues, 0, numBytes);
int extraBytes = bmpData.Stride % 3;
// convert to greyscale
for (int i = 0; i < rect.Width; i++)
{
for (int j = 0; j < rect.Height; j++)
{
int idx = j * bmpData.Stride + i * 3;
byte grey;
if (writingInWhite)
{
int sum = rgbValues[idx] + rgbValues[idx + 1] + rgbValues[idx + 2];
grey = Math.Max(Math.Max(rgbValues[idx], rgbValues[idx + 1]), rgbValues[idx + 2]);
}
else
{
int sum = rgbValues[idx] + rgbValues[idx + 1] + rgbValues[idx + 2];
grey = (byte)(sum / 3);
}
rgbValues[idx] = grey;
rgbValues[idx + 1] = grey;
rgbValues[idx + 2] = grey;
}
}
// Copy the RGB values back to the bitmap
Marshal.Copy(rgbValues, 0, ptr, numBytes);
dest.UnlockBits(bmpData);
return dest;
}