Предполагается Imports System.Runtime.InteropServices, System.Drawing.Imaging
в верхней части файла кода. (LockBits не так уж и сложен, я много работаю с ним и предпочитаю VB.NET, а не C #.)
Private Sub To4BitGrayScale(ByVal b As Bitmap)
Dim bd As BitmapData = b.LockBits(New Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, ImageFormat.Format24BppRgb)
Dim arr(bd.Width * bd.Height * 3 - 1) As Byte
Marshal.Copy(bd.Scan0, arr, 0, arr.Length)
For i As Integer = 0 To arr.Length - 1 Step 3
Dim c As Color = Color.FromArgb(255, arr(i), arr(i + 1), arr(i + 2))
' Convert c to grayscale however you want; weighted, average, whatever.
arr(i) = c.R
arr(i + 1) = c.G
arr(i + 2) = c.B
Next
Marshal.Copy(arr, 0, bd.Scan0, arr.Length)
b.UnlockBits(bd)
End Sub
Этот метод, конечно, не быстрый (для 8-мегапиксельного изображения у меня это занимает около 1-2 секунд), но это не плохо.