Bitmap ClassThe Bitmap class is the generalization of the Image class. Note above that, the PictureBox class contains a refrence of the image class, but the Image class is an abstract class, so its objects can be instantiated and PictureBox objects contains the instantiations of the Image class's derived classes, one of which is the Bitmap class..Constructor: Bitmap class contains 12 constructors that construct the Bitmap object from different parameters. It can construct the Bitmap from another bitmap, and the string address of the image. It also provides the constructors the Bitmap object from Bitmap( int width , int height ).
PixelFormat: PixelFormat is the public property of the image of this image object.
Clone: This is the overloaded function of the Bitmap class inherited from the Object class that returns the copy of the object on which the function was orignaly invoked.
GetPixel: The public function that get the color of the specified pixel.
SetPixel: The public function that sets the color of the specified pixel.
LockBits and UnLockBits: The public functions in the class that locks and unlocks the specified area of the image into the memory. The paramenters of the LockBits function are, a Rectangle object specifying the area to be Locked, then 2 integers specifying the access level for the object and the other showing the format of the image. This is done through two enumirations like ImageLockMode, and PixelFormat. They are narrated after this class. The LockBits returns the object of the BitmapData class and UnLockBits takes the object of the BitmapData class. BitmapData LockBits( Rectangle , ImageLockMode , PixelFormat );ImageLockMode EnumirationSpecifies flags that are passed to the flags parameter of the LockBits method. It has four members.
ReadOnly: Specifies that a portion of the image is locked for reading.
ReadWrite: Specifies that a portion of the image is locked for reading or writing.
UserInputBuffer: Specifies that the buffer used for reading or writing pixel data is allocated by the user.
WriteOnly: Specifies that a portion of the image is locked for writing.
BitmapData classScan0: The address of the first byte in the locked array. If whole of the image is locked, then it is the first byte of the image.
Stride: The width, in bytes, of a single row of pixel data in the locked array. This width is a multiple, or possibly sub-multiple, of the pixel dimensions of the image and may be padded out to include a few more bytes. I'll explain why shortly.
Width: The width of the locked image.
Height: The height of the locked image.
PixelFormat: The actual pixel format of the data.
PixelFormat ClassThe pixel format defines the number of bits of memory associated with one pixel of data. In other words the format defines the order of the color components within a single pixel of data. Normaly, PixelFormat.Format24bppRgb is used. PixelFormat.Format24bppRgb specifies that the format is 24 bits per pixel; 8 bits each are used for the red, green, and blue components. In the 24 bit format image, the image consists of pixels consisting of 3 bytes, one for each red, green, and blue. The first byte in the image contains the blue color, the second byte contains the green color, and the third byte contains the red color of the pixel, and they form the color of the specified pixel.
Basic Layout of the Locked ArrayScan0 is the pointer to the 1st byte in the pixel array of the image which contains Height no. of rows and each row contains Stride no. of bytes in every row as shown in the diagram:
Each row contains the data of Width no. of pixels, where each pixel consists of PixelFormat no. of bytes. Thus total space taken by the Width no. of pixels is
Total space taken by Width no. Pixels = Width( no. of Pixels ) X PixelFormat( no. of bytes per pixel )
This space is aproximately equal to the Stride, but not exactly equal to it. In fact due to efficiency reasons, it is ensured that the Stride of an image contains a no. multiple of 4. For example, if an image is in 24 bits per pixel, and contains 25 pixel in each row, then it needs total space in each row equal to ( 75 = 3 X 25 ), but 75 is not the multiple of 4. Hence, the next multiple of 4 is used and in this case it is 76. Hence, 1 byte is remained unused as shown by the black area in every row in the above diagram. If space needed by the Width no. bytes is a multiple of 4, then the Stride is equal to it, and hence, there is no unused space mentioned as black area in the above diagram.
Iterating through the Image
First of all create the Bitmap object as:
Bitmap image = new Bitmap( "c:\\images\\image.gif" );
Then get the BitmapData object from it by calling the Lock method as:
BitmapData data = image.LockBits( new Rectangle( 0 , 0 , image.Width , image.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
Then you can iterate in the image as:
unsafe {
byte* imgPtr = ( byte* )( data.Scan0 );
for( int i = 0 ; i <>
{
for( int j = 0 ; j <>
{
// write the logic implementation here
ptr += 3;
}
ptr += data.Stride - data.Width * 3;
}
}
Here unsafe, shows that you need to use the pointers in the unmanaged block, and the statement:
ptr += data.Stride - data.Width * 3;
shows that you need to skip the unused space.