Click here to Skip to main content
15,885,914 members
Articles / Programming Languages / C#
Alternative
Tip/Trick

Convert RGB to Gray Scale without using Pointers

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
18 Jan 2012CPOL 7.5K   1  
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...

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.


C#
struct BGR { public byte B, G, R; }

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, PixelFormat.Format24bppRgb); // 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
            BGR* Bmp= (BGR*)(BMPData.Scan0 + i * BMPData.Stride);
            BGR* Gray= (BGR*)(GRAYData.Scan0 + i * GRAYData.Stride);

            // Loop on the pixels
            for (int j= 0; j < Width; j++, Bmp++, Gray++)
            {
                // Extract the luminance of a source pixel using 14 bits fixed-point
                byte Y= (byte)((4897 * Bmp->R + 9617 * Bmp->G + 1868 * Bmp->B) >> 14);

                // Assign it to the corresponding destination pixel
                Gray->R= Gray->G= Gray->B= Y;
            }
        }
    }

    // Release
    BMP.UnlockBits(BMPData);
    GRAY.UnlockBits(GRAYData);

    picGray.Image= GRAY;
}

It is no big deal to adapt this function to the Format32bppArgb format.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO VISION fOr VISION
Belgium Belgium
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.

Comments and Discussions

 
-- There are no messages in this forum --