A piece of warning, though: the LockBits
method is not a transparent one, it does image format conversion before returning a pointer to the bitmap (this is why it has a PixelFormat
argument). And conversely, the UnlockBits
method converts back to the original format. My best guess is that when the requested format is the native one (PixelFormat
property of the Bitmap
), no conversion takes place.
struct BGR { public byte B, G, R; }
void GrayConversion()
{
Bitmap BMP= (Bitmap)pictureBox1.Image;
int Width= BMP.Width, Height= BMP.Height;
Bitmap GRAY= new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
BitmapData BMPData= BMP.LockBits(new Rectangle(0, 0, Width, Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData GRAYData= GRAY.LockBits(new Rectangle(0, 0, Width, Height),
ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
for (int i= 0; i < Height; i++)
{
unsafe
{
BGR* Bmp= (BGR*)(BMPData.Scan0 + i * BMPData.Stride);
BGR* Gray= (BGR*)(GRAYData.Scan0 + i * GRAYData.Stride);
for (int j= 0; j < Width; j++, Bmp++, Gray++)
{
byte Y= (byte)((4897 * Bmp->R + 9617 * Bmp->G + 1868 * Bmp->B) >> 14);
Gray->R= Gray->G= Gray->B= Y;
}
}
}
BMP.UnlockBits(BMPData);
GRAY.UnlockBits(GRAYData);
picGray.Image= GRAY;
}
It is no big deal to adapt this function to the Format32bppArgb
format.
I fell into applied algorithmics at the age of 16 or so. This eventually brought me to develop machine vision software as a professional. This is Dreamland for algorithm lovers.