Saturday, July 26, 2014

Reading a bmp image directly using C++: Part 2

As discussed in an earlier post about the header portion of a bmp file and the information it contains.

We can observe that byte 18 and byte 22 respectively contain the height and width of the image which we will be using to read the total information in the image.

Also note that the total size of the header is 54 bytes, which is the offset obtained before we can start getting pixel level data.

Initalise the function as :
unsigned char* ReadBMP(char* filename, int* array)

Notice that we are reading the data into a 1-D array which we can always read as 3D (length, width, and colorscale) while reading as-

pixel at position x,y would be array[width*x+y]

Red value of pixel x,y would be [widht*x+y +0 ]
Blue value of pixel x,y would be [width*x+y +1 ]
Green value of pixel x,y would be [width*x+y +2 ]

To start reading the image, we will first open the file and store it in a variable img as follows-
 FILE* img = fopen(filename, "rb");   //read the file
Allocate 54 bytes for the image header and read it using fread-
unsigned char header[54];
fread(header, sizeof(unsigned char), 54, img); // read the 54-byte header
Obtain the height and width information from the header as discussed earlier-
   // extract image height and width from header   
  int width = *(int*)&header[18];       
There is extra padding present generally in BMP files if the image width/row is not a multiple of 4 bytes. Also the actual row size is 3 times the width returned by the header since we have three values each of R, G and B respectively being stored for each pixel. In BMP windows save pixels as B, G, R format instead of the conventional R, G,B order. We will be taking care of this as well.

  int padding=0; while (width*3+padding) % 4!=0 padding++;
We will create a dummy width - widthnew which we will used for reading the file

  int widthnew=width*3+padding;
The final piece of code is to read the pixels one by one through iteration-

 for (i=0; i<height; i++ ) {                                      

fread( data, sizeof(unsigned char), widhthnew, img);

for (int j=0; j<width*3; j+=3)                                  

 { //Convert BGR to RGB and store                         

array[i*width+j+0] = data[j+2];                                

array[i*width+j+1] = data[j+1];                                

array[i* width+j+2] = data[j+0]; }}                          

fclose(img); //close the file   

The complete code has been shared in the nextpost

1 comment:

  1. impossible to declare an array with the correct size for this without using vanilla C