BMP文件转二维二进制数组时蓝点位置偏移问题及读取顺序需求咨询
Fixing Incorrect Blue Pixel Position in BMP to 0/1 Array Conversion
Hey there! Let's break down why your blue pixels are showing up in the wrong spots and how to fix this issue.
What's Causing the Problem?
The core issue here is how BMP files store pixel data:
- BMPs store pixels starting from the bottom-left corner of the image, then moving row by row upwards to the top-right.
- Your current code iterates
ifrom 0 tohight-1(treatingi=0as the top row of the image), which means you're filling yourbmparray from top to bottom—opposite of how the data is stored. This flips the entire image vertically, making your blue pixels appear in the wrong positions.
On top of that, your code has two other small but critical oversights:
- Uninitialized values: You only set
bmp[i][j] = 1for blue pixels, but never initialize non-blue pixels to 0. This can lead to random garbage values in your output. - Missing row padding handling: BMP files require each row's byte count to be a multiple of 4. If your image width isn't a multiple of 4, there will be extra padding bytes at the end of each row. Skipping these will throw off all subsequent pixel reads.
How to Fix It
Solution 1: Read Pixels in the Correct Vertical Order (Most Efficient)
Adjust your reading loop to start from the bottom row of your bmp array and work upwards, while also handling padding and initializing values:
unsigned int temp; int i, j, width, height; // Fixed "hight" to standard spelling "height" int** bmp; FILE* pic; fopen_s(&pic, "fishpool2.bmp", "rb"); pic_size(pic, &width, &height); printf_s("width = %d\theight = %d\n", width, height); fseek(pic, 54, SEEK_SET); // Skip BMP header (54 bytes for standard BMP) // Calculate row padding once (since width doesn't change) int padding = (4 - (width * 3) % 4) % 4; // Read from bottom row to top row of the image for (i = height - 1; i >= 0; i--) { for (j = 0; j < width; j++) { temp = fgetc(pic); // Read blue channel first (BMP uses BGR order) fgetc(pic); // Skip green channel fgetc(pic); // Skip red channel // Set 1 for blue pixels, 0 otherwise if (temp >= 155 && temp <= 245) { bmp[i][j] = 1; } else { bmp[i][j] = 0; } } // Skip the padding bytes at the end of the row fseek(pic, padding, SEEK_CUR); } // Print the result for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { printf_s("%d", bmp[i][j]); } puts(""); }
Solution 2: Reverse Rows After Reading
If you prefer to keep your original reading loop structure, you can read the pixels as you were, then reverse the rows of your bmp array before printing:
// ... [your original reading code here, but add bmp[i][j] = 0 for non-blue pixels and handle padding] ... // Reverse the rows to fix vertical orientation for (i = 0; i < height / 2; i++) { int* temp_row = bmp[i]; bmp[i] = bmp[height - 1 - i]; bmp[height - 1 - i] = temp_row; } // ... [print the array as before] ...
Key Notes
- Always remember BMP's BGR pixel order and bottom-up storage—these are common pitfalls!
- Don't forget row padding, especially for images with widths that aren't multiples of 4.
- Initializing all array values (setting non-blue pixels to 0) ensures your output is consistent, no matter what garbage values were in memory initially.
内容的提问来源于stack exchange,提问作者Lior
相关产品推荐
相关产品推荐

