将 BMP 像素数据加载到数组 C 中

Posted

技术标签:

【中文标题】将 BMP 像素数据加载到数组 C 中【英文标题】:Load BMP pixel data into array C 【发布时间】:2013-07-31 16:19:42 【问题描述】:

我正在尝试将像素数据从位图中读取到结构化数组(其中包含 R、G 和 B 整数,用于颜色)。我使用 12x12px 的图像只是为了测试(因为我相信 bmp 规范说像素数据在每行的末尾用零填充以使其字对齐。12px 宽度自动字对齐。

这是我正在使用的代码。 INFOHEADERFILEHEADER 被完美解析,并创建了 IMAGEs im 的 12x12 2D 数组。但是打印每个像素的 RGB 数据会很垃圾。

typedef struct __attribute__((__packed__)) 
    unsigned char  b;
    unsigned char  g;
    unsigned char  r;
 IMAGE;

int main(void) 
    FILEHEADER fh;
    INFOHEADER ih;
    FILE *img = fopen("pic.bmp", "rb");
    fread(&fh, sizeof(unsigned char), sizeof(FILEHEADER), img);
    fread(&ih, sizeof(unsigned char), sizeof(INFOHEADER), img);

    IMAGE im[ih.width][ih.height];
    fseek(img, fh.imageDataOffset, 0);
    int i, j;
    for (i = ih.height-1; i >= 0; i--) 
        for (j = 0; j < ih.width; j++) 
            fread(&im[i][j], sizeof(unsigned char), sizeof(IMAGE), img);
            printf("%x%x%x ", im[i][j].r, im[i][j].g, im[i][j].b);
        
        printf("\n");
    
    printf("w = %d, h = %d\n", ih.width, ih.height);

但是,对于 12x12px 完全白色的位图,输出:

ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff 
ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff 
ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff 
ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff ffffff 
000 ca800 ff574b 007f 001 000 b000 574bc9 07fff 44c40 ff8690 007f 
9077b0 7fff86 8000 574bca 07fff 0a00 ff7482 007f 4bc950 7fff57 2f00 86906d 
07fff 60a50 ff8690 007f 4bc9d0 7fff57 ee00 87418 000 c9300 ff574b 007f 
4bc8f0 7fff57 700 868b3c 07fff 400 000 000 820a0 7fff74 3000 574bc9 
07fff 6000 1877 000 0100 000 000 004 000 1000 000 000 
820a0 7fff74 000 0010 000 6000 1874 000 4bc8d0 7fff57 b300 868b31 
000 38b30 051f9 000 000 000 000 000 000 010 000 000 
745069 018 f700 ffffff 181a4 080 000 000 01f5 0140 000 000 

谁能看到我做错了什么?会不会是对齐问题?

谢谢

编辑:

这是位图文件底部的屏幕截图。似乎有 144 (12x12) 个白色像素(突出显示)。最后两个零是填充。尽管如此,我的程序没有正确解析它仍然没有意义。

【问题讨论】:

您正在阅读循环中交换高度和宽度。不是这里的问题(对于方形图像),但您可能想要更正它。你能验证 sizeof(IMAGE) 是 3 吗?另外,您能否在十六进制查看器中打开 BMP 图像并验证 rgb 三元组之间没有 0 填充字节? 是 sizeof(IMAGE) 是 3。看看我对填充的编辑 你试过使用解压的结构体吗? 是的,解压后的结构仍然不起作用 顺便说一句,我还以为会是“打包”而不是“_ 打包 _”。 【参考方案1】:

好吧,原来我将空白 bmp 保存为 8 位而不是 24 位。 8bit使用颜色表,每个像素引用颜色表中的一个条目来获取它的数据。 24bit bmp每个像素使用3个字节,每个字节代表一个R、G、B值,所以不需要色表。

【讨论】:

以上是关于将 BMP 像素数据加载到数组 C 中的主要内容,如果未能解决你的问题,请参考以下文章

C将bmp像素读入二维数组

加载 bmp 图像 OPENGL 3.x - 只加载一个像素?

Re: 快速从 UIImage/CGImage 获取像素数据作为数组

将数据从文件加载到c中的数组

C/C++中如何将文件读取为二进制数据到数组中,再从数组中读取二进制流还原为文件,主要是后一步

C语言读取1位的BMP图