Sunday, June 20, 2010

Process Bitmap Faster In .NET

In .NET (C# or VB.net) you can process Bitmap pixel by pixel.

Here is the example of simple code. ( Use Example of Gray Scale)

System.Drawing.Image img = System.Drawing.Bitmap.FromFile(@"C:\Test.jpg");
Bitmap bmp = (Bitmap)img;
         for (int x = 0; x < bmp.Width; x++)
         {
             for (int y = 0; y < bmp.Height; y++)
             {
                Color c =  bmp.GetPixel(x, y);
                int gray = (int)((c.R + c.G + c.B)/3);
                bmp.SetPixel(x,y,Color.FromArgb(gray,gray,gray));
             }
         }

Above code works fine but it takes to much time to process.In order to process Bitmap Image Faster “BitmapData” is powerful class in .NET. Here is the example of that class.

System.Drawing.Image img = System.Drawing.Bitmap.FromFile(@"C:\Test.jpg");
Bitmap bmp = (Bitmap)img;           
System.Drawing.Imaging.BitmapData data = bmp.LockBits(new Rectangle() { X = 0, Y = 0, Width = bmp.Width, Height = bmp.Height }, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
IntPtr ptr = data.Scan0;           
int bytes  =data.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];           
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
int val = 0;
for (int counter = 0; counter < rgbValues.Length; counter += 3)
{
    val = rgbValues[counter + 0] + rgbValues[counter + 1] + rgbValues[counter + 2];
    rgbValues[counter+0] =  (byte)(val/3);
    rgbValues[counter+1] =  (byte)(val/3);
    rgbValues[counter+2] =  (byte)(val/3);
}
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
bmp.UnlockBits(data);      

This code works must faster than previous code. Test it with PictureBox Control and See the effect… :)

No comments: