Convert RGB to Gray Scale without using Pointers





0/5 (0 vote)
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...
- 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. - 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?
If their implementation is opaque to the compiler too, no code optimization can be done via inlining.
void GrayConversion()
{
Bitmap BMP = (Bitmap)pictureBox1.Image; // BMP is the source image
int Width = BMP.Width, Height = BMP.Height;
Bitmap GRAY = new Bitmap(Width, Height); // GRAY is the resultant image
// Access the bitmap data
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);
// Loop on the rows
for (int i = 0; i < Height; i++)
{
unsafe
{
// Start-of-row addresses
byte* Bmp = (byte*)BMPData.Scan0 + i * BMPData.Stride;
byte* Gray = (byte*)GRAYData.Scan0 + i * GRAYData.Stride;
// Loop on the pixels
for (int j = 0; j < Width; j++, Bmp += 3, Gray += 3)
{
// Extract the luminance of a source pixel using 14 bits fixed-point
byte Y = (byte)((4897 * Bmp[2] + 9617 * Bmp[1] + 1868 * Bmp[0]) >> 14);
// Assign it to the corresponding destination pixel
Gray[2] = Gray[1] = Gray[0] = Y;
}
}
}
// Release
BMP.UnlockBits(BMPData);
GRAY.UnlockBits(GRAYData);
picGray.Image = GRAY;
}