Пример преобразования цветного изображения в черно белое на C#
Возможно есть много методов преобразования цветного изображения в чёрно белое, и возможно даже более совершенных, но на данный момент представленный ниже метод, является самым быстрым, среди известных мне.
Преобразование использует только стандартные библиотеки.
Суть метода заключается не в работе с самой картинкой а в работе с блоком данных, если очень просто - то замораживаем область данных с картинкой в памяти - изменяем её как нам надо, и возвращаем всё на круги своя.
Долго рассказывать не имеет смысла, сразу привожу пример процедуры преобразования изображения Bitmap с комментариями:
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);
}
Перебор массива байтов осуществляется с шагом 3 поскольку каждый пиксел кодируется 3-мя байтами R G B.
В цикле составляющие R G и B суммируются, вычисляется среднее значение из трёх составляющих, после чего вместо значений R G и B помещается это среднее значение, таким образом задаётся необходимый тон серого.
Для работы процедуры необходимо подключить:
System.Drawing.Imaging;
System.Runtime.InteropServices;