private void MakeGray(Bitmap bmp)
{
// Задаём формат Пикселя.
PixelFormat pxf = PixelFormat.Format24bppRgb;
// Получаем данные картинки.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
//Блокируем набор данных изображения в памяти
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);
// Получаем адрес первой линии.
IntPtr ptr = bmpData.Scan0;
// Задаём массив из Byte и помещаем в него надор данных.
// int numBytes = bmp.Width * bmp.Height * 3;
//На 3 умножаем - поскольку RGB цвет кодируется 3-мя байтами
//Либо используем вместо Width - Stride
int numBytes = bmpData.Stride * bmp.Height;
int widthBytes = bmpData.Stride;
byte[] rgbValues = new byte[numBytes];
// Копируем значения в массив.
Marshal.Copy(ptr, rgbValues, 0, numBytes);
// Перебираем пикселы по 3 байта на каждый и меняем значения
for (int counter = 0; counter < rgbValues.Length; counter += 3)
{
int value = rgbValues[counter] + rgbValues[counter + 1] + rgbValues[counter + 2];
byte color_b = 0;
color_b = Convert.ToByte(value / 3);
rgbValues[counter] = color_b;
rgbValues[counter + 1] = color_b;
rgbValues[counter + 2] = color_b;
}
// Копируем набор данных обратно в изображение
Marshal.Copy(rgbValues, 0, ptr, numBytes);
// Разблокируем набор данных изображения в памяти.
bmp.UnlockBits(bmpData);
}