- You shouldn't rely on methods from the .NET classes (
Bitmap::SetPixel
, Bitmap::GetPixel
, Color::FromArgb
) in the inner loop as these are called intensively, million times per image, and their implementation are opaque to you. If their implementation is opaque to the compiler too, no code optimization can be done via inlining.
- Doing the linear combinations using floating-point arithmetic is overkill. Fixed-point is good enough. You will be penalized by the overhead of data type conversion and floating-point arithmetic.
- What's so scary with pointers ? Is the code below less readable?
void GrayConversion()
{
Bitmap BMP = (Bitmap)pictureBox1.Image;
int Width = BMP.Width, Height = BMP.Height;
Bitmap GRAY = new Bitmap(Width, Height);
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
{
byte* Bmp = (byte*)BMPData.Scan0 + i * BMPData.Stride;
byte* Gray = (byte*)GRAYData.Scan0 + i * GRAYData.Stride;
for (int j = 0; j < Width; j++, Bmp += 3, Gray += 3)
{
byte Y = (byte)((4897 * Bmp[2] + 9617 * Bmp[1] + 1868 * Bmp[0]) >> 14);
Gray[2] = Gray[1] = Gray[0] = Y;
}
}
}
BMP.UnlockBits(BMPData);
GRAY.UnlockBits(GRAYData);
picGray.Image = GRAY;
}