Home > Enterprise >  bmp file into 2D binary array
bmp file into 2D binary array

Time:06-10

I need to read a bmp file and display it as a 2d array of 1 and 0

enter image description here

if the pixel is blue the value in the array is 1 and 0 for white.

unsigned int temp;
int i, j, width, hight;
int** bmp;
FILE* pic;
fopen_s(&pic, "fishpool2.bmp", "rb");
pic_size(pic, &width, &hight);
printf_s("width = %d\thight = %d\n", width, hight);
fseek(pic, 54, SEEK_SET);
for (i = 0; i < hight; i  ) { 
    for (j = 0; j < width; j  ) {
        temp = fgetc(pic);
        fgetc(pic);
        fgetc(pic);
        if (temp >= 155 && temp <= 245) bmp[i][j] = 1;
        
    }
}
for (i = 0; i < hight; i  ) {
    for (j = 0; j < width; j  ) {
        printf_s("%d", bmp[i][j]);
    }
    puts("");
}

this is what I have so far. I didn't include the code part with i allocate memory and getting the height and width of the pic. I don't know why but when I run the code the blue spots aren't in the correct position.

(I need to read the picture from the bottom left to top right) enter image description here

CodePudding user response:

Read this.

BMP file format - Wikipedia

The BMP file format is complex with many variations. Which documents did you look at and code? And you seem to be limiting yourself to specific formats and parameters to read, does that match the actual file you are trying to read?

CodePudding user response:

The stride between two consecutive rows is rounded to 4 bytes. From https://en.wikipedia.org/wiki/BMP_file_format#Pixel_array_(bitmap_data)

For file storage purposes, only the size of each row must be a multiple of 4 bytes while the file offset can be arbitrary.

Therefore in your case (width = 110), each line is 330 bytes long. The stride is rounded to the next multiplicity of 4 which is 332. Therefore the program should fetch 332-330 = 2 extra bytes after processing each row:

for (i = 0; i < hight; i  ) { 
    for (j = 0; j < width; j  ) {
        temp = fgetc(pic);
        fgetc(pic);
        fgetc(pic);
        if (temp >= 155 && temp <= 245) bmp[i][j] = 1;
        
    }
    // fetch 2 extra bytes
    fgetc(pic);
    fgetc(pic);    
}

The more robust solution could be:

size_t row_size = width * 3;
size_t row_size_rounded = (row_size   3) / 4 * 4;
size_t padding = rows_size_rounded - rows_size;

...

for (i = 0; i < hight; i  ) { 
    for (j = 0; j < width; j  ) {
        ...
    }
    for (size_t p = 0; p < padding;   p)
        fgetc(pic);
}

CodePudding user response:

When approaching a well-known file format, it is usually a good idea not to "reinvent the wheel". Rather, you look for a library which reads/parses this format into something your program can use more easily. If you search on GitHub, for example, you'll find several BMP reading/writing libraries you could use.

Or you could go for the "swiss army knife" which is ImageMagic; see here.

  •  Tags:  
  • c
  • Related