我遇到的问题是我所做的代码应该以bmp(位图)格式显示图像每个像素的RGB颜色值的字节。
我知道在windows api中如何以更实际的方式使用位图,但由于我希望最终代码在操作系统方面是可移植的,我创建了结构,我只是阅读C的基础知识
以下是代码:
#include <stdio.h>
#include <stdlib.h>
unsigned char *readBMP(char *filename, int *size) {
int width, height;
unsigned char *data;
unsigned char info[54];
FILE *file = fopen(filename, "rb");
if (file == NULL)
return 0;
fread(info, sizeof(unsigned char), 54, file); // read the 54-byte header
// extract image height and width from header
width = *(int *) &info[18];
height = *(int *) &info[22];
*size = 3 * width * height;
data = (unsigned char *) malloc(*size * sizeof(unsigned char)); // allocate 3 bytes per pixel
fread(data, sizeof(unsigned char), (size_t) *size, file); // read the rest of the data at once
for (int i = 0; i < *size; i += 3) {
unsigned char tmp = data[i];
data[i] = data[i + 2];
data[i + 2] = tmp;
}
fclose(file);
return data;
}
int main() {
int size = 0;
char filename[] = "output.bmp";
unsigned char *data = readBMP(filename, &size);
for (int i = 0; i < size; i++) {
printf("%d. %d\n", i + 1, (int) data[i]);
if ((i + 1) % 3 == 0)
printf("\n");
}
free(data);
return 0;
}
像素的RGB代码:
(0, 0, 0), (0, 0, 255),
(0, 255, 0), (0, 255, 255),
(255, 0, 0), (255, 0, 255);
我试图“读取”的图像是2x3像素位图:https://prnt.sc/gnygch
我的输出是:
1. 255
2. 0
3. 0
4. 255
5. 0
6. 255
7. 0
8. 0
9. 0
10. 255
11. 0
12. 255
13. 0
14. 0
15. 255
16. 0
17. 0
18. 0
第一个读数甚至匹配位图底部的像素,但其他读数与其他像素不匹配,至少不按照排列顺序排列。
谁能看到我做错了什么?
答案 0 :(得分:1)
位图的大小不是width * height * 3
。应使用
size = ((width * bitcount + 31) / 32) * 4 * height;
在这种情况下,bitcount
为24。
必须填充24位位图中的行。您还需要确保您正在读取24位位图。对于32位位图需要不同的算法,托盘位图需要不同的算法。
从下到上读取行。
以下是24位的示例。
您可能仍会遇到此代码的其他问题。最好将库用于这些功能。如果您不想使用Windows功能,请使用可在不同操作系统上使用的第三方库。那里有很多这样的图书馆。
int main()
{
int width, height, padding, bitcount, size;
unsigned char *data = 0;
unsigned char info[54] = { 0 };
FILE *file = fopen("output.bmp", "rb");
if(!file)
return 0;
fread(info, 1, 54, file);
width = *(int*)(info + 18);
height = *(int*)(info + 22);
bitcount = *(int*)(info + 28);
size = ((width * bitcount + 31) / 32) * 4 * height;
padding = width % 4;
if(bitcount != 24) //this code works for 24-bit bitmap only
goto error;
data = malloc(size);
fread(data, 1, size, file);
for(int row = height - 1; row >= 0; row--)
{
for(int col = 0; col < width; col++)
{
int p = (row * width + col) * 3 + row * padding;
printf("%02X%02X%02X ", data[p + 0], data[p + 1], data[p + 2]);
}
printf("\n");
}
error:
if(file) fclose(file);
if(data) free(data);
return 0;
}