Bitmaps in memory

C# reads almost any bitmap file format, so it is simple to load it into a Bitmap object (for example by the Image.FromFile method). Bitmap class has very comfortable methods to manipulate pixels, but these are too slow for the requirement of the image processing. If you are going to create fast image manipulation, you should avoid of using GetPixel, SetPixel methods. Instead of them a current bitmap need to be converted to a byte array. Image processing procedures run much faster on a byte array than a bitmap object.
BitmapData class:
Properties:

PixelFormat can be Format8bppRgb, Format24bppRgb or Format32bppRgb.

What is the stride parameter? Stride is padded. The following table illustrates the relationship between width and stride.

width stride
1 4
2 4
3 4
4 4
5 8
6 8
7 8
8 8
9 12
10 12
11 12
12 12
. .
. .
. .

You do not need to calculate the strange stride parameter, because you can get it from BitMapData. It is required to calculate the length of a bitmap in bytes:


int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];

Conversion of a Bitmap to a byte array and vice versa

The following code shows how to do these:


        //convert image to byte array
        
        public byte[] BitmapToByteArray(Bitmap img)      //img is the input image. Image width and height in pixels. PixelFormat is 24 bit per pixel in this case
        {
            BitmapData bmpData=img.LockBits(new Rectangle(0,0,img.Width,img.Height),ImageLockMode.ReadOnly,img.PixelFormat);    //define and lock the area of the picture with rectangle
            int pixelbytes =Image.GetPixelFormatSize(img.PixelFormat) / 8;     //for 24 bpp the value of pixelbytes is 3, for 32 bpp is 4, for 8 bpp is 1
            IntPtr ptr=bmpData.Scan0;      //this is a memory address, where the bitmap starts
            Int32 psize = bmpData.Stride * bmpData.Height;      // picture size in bytes
            byte[] byOut=new byte[psize];     //create the output byte array, which size is obviously the same as the input one

            System.Runtime.InteropServices.Marshal.Copy(ptr, byOut, 0, psize);      //this is a very fast method, which copies the memory content to byteOut array, but implemented for 24 bpp pictures only
            img.UnlockBits(bmpData);      //release the locked memory
            return byOut;      //  e finita la commedia
        }



        //convert byte array to bitmap
        
        public Bitmap ByteArrayToBitmap(byte[] byteIn, int imwidth, int imheight)     // byteIn the input byte array. Picture size should be known
        {
            Bitmap picOut=new Bitmap(imwidth,imheight,PixelFormat.Format24bppRgb);  //define the output picture
            BitmapData bmpData = picOut.LockBits(new Rectangle(0, 0, imwidth, imheight), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            IntPtr ptr=bmpData.Scan0;
            Int32 psize =   bmpData.Stride*imheight;
            System.Runtime.InteropServices.Marshal.Copy(byteIn,0,ptr,psize);
            picOut.UnlockBits(bmpData);
            return picOut;      //  e finita la commedia
        }