0

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

1
  • note that stride between images rows is rounded to 4 bytes. You may need to fetch a few extra padding bytes before starting a new row. Commented Jun 9, 2022 at 14:04

3 Answers 3

2

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?

Sign up to request clarification or add additional context in comments.

2 Comments

i'm new to C so i dont know much on the formats and parameters to read.. i was just given the bmp file ( i posted the file here at the top) and supposed to transfer it to a 2d array and print it. i thought this was the best way (that i know of) to do it but it just doesnt work very good..
If the structure is as expected, as @tstanisl says, it might be a good to add processing to correctly skip the per-row padding.
1

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);
}

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.