Saturday, July 26, 2014

Code for reading bmp image files directly in C/C++

We have discussed the process of reading BMP files in earlier post1 and post2 in detail. You can find the code below:

unsigned char* ReadBMP(char* filename, int* array)

{

 FILE* img = fopen(filename, "rb");   //read the file


unsigned char header[54];
fread(header, sizeof(unsigned char), 54, img); // read the 54-byte header


   // extract image height and width from header
 int width = *(int*)&header[18];    
 int height = *(int*)&header[22];    
 int padding=0; while (width*3+padding) % 4!=0 padding++;

 int widthnew=width*3+padding;

 unsigned char* data = new unsigned char[widthnew];

 for (int 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
}



Please post incase you face any difficulty in running the codes.

12 comments:

  1. There are a lot of errors. Havent you run it even ones ? I think not. Even 'i' in the first for loop is not defined ..

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Is there any chance that we can see the correct code?

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. how to store pixel values into 2D array

    ReplyDelete
  6. Plz can u give me soln. How to output that stored data to output console in c++

    ReplyDelete
  7. Plz can u give me soln. How to output that stored data to output console in c++

    ReplyDelete
  8. Good work and thanks for the code.
    There is a functional bug which took me around 2hours to point out.
    array[i*width+j+0] = data[j+2]; should be array[i*width*3+j+0]. Notice that you have to multiply "i * width * 3".

    Here is the working code:
    static unsigned char *texels;
    static int width, height;

    static void readBmp(char *filename)
    {
    FILE *fd;
    fd = fopen(filename, "rb");
    if (fd == NULL)
    {
    printf("Error: fopen failed\n");
    return;
    }

    unsigned char header[54];

    // Read header
    fread(header, sizeof(unsigned char), 54, fd);

    // Capture dimensions
    width = *(int*)&header[18];
    height = *(int*)&header[22];

    int padding = 0;

    // Calculate padding
    while ((width * 3 + padding) % 4 != 0)
    {
    padding++;
    }

    // Compute new width, which includes padding
    int widthnew = width * 3 + padding;

    // Allocate memory to store image data (non-padded)
    texels = (unsigned char *)malloc(width * height * 3 * sizeof(unsigned char));
    if (texels == NULL)
    {
    printf("Error: Malloc failed\n");
    return;
    }

    // Allocate temporary memory to read widthnew size of data
    unsigned char* data = (unsigned char *)malloc(widthnew * sizeof (unsigned int));

    // Read row by row of data and remove padded data.
    for (int i = 0; i<height; i++)
    {
    // Read widthnew length of data
    fread(data, sizeof(unsigned char), widthnew, fd);

    // Retain width length of data, and swizzle RB component.
    // BMP stores in BGR format, my usecase needs RGB format
    for (int j = 0; j < width * 3; j += 3)
    {
    int index = (i * width * 3) + (j);
    texels[index + 0] = data[j + 2];
    texels[index + 1] = data[j + 1];
    texels[index + 2] = data[j + 0];
    }
    }

    free(data);
    fclose(fd);
    }

    ReplyDelete