c从BMP获取数据

c从BMP获取数据,c,bmp,C,Bmp,我发现自己正在编写一个简单的程序来从bmp文件中提取数据。我刚刚开始,我正处于WTF的某个时刻 当我运行程序并提供此图像时: 我得到输出: type: 19778 size: 12 res1: 0 res2: 54 offset: 2621440 实际图像大小为786486字节。为什么我的代码报告12字节 中指定的标头格式, 匹配我的BMP\u文件\u头结构。那么,为什么它会被错误的信息填满呢 图像文件似乎没有损坏,其他图像的输出也同样错误。我错过了什么 #include <stdio.

我发现自己正在编写一个简单的程序来从bmp文件中提取数据。我刚刚开始,我正处于WTF的某个时刻

当我运行程序并提供此图像时:

我得到输出:

type: 19778
size: 12
res1: 0
res2: 54
offset: 2621440
实际图像大小为786486字节。为什么我的代码报告12字节

中指定的标头格式, 匹配我的BMP\u文件\u头结构。那么,为什么它会被错误的信息填满呢

图像文件似乎没有损坏,其他图像的输出也同样错误。我错过了什么

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    unsigned short type;
    unsigned int size;
    unsigned short res1;
    unsigned short res2;
    unsigned int offset;
} BMP_FILE_HEADER;

int main (int args, char ** argv) {
    char *file_name = argv[1];

    FILE *fp = fopen(file_name, "rb");

    BMP_FILE_HEADER file_header;

    fread(&file_header, sizeof(BMP_FILE_HEADER), 1, fp);

    if (file_header.type != 'MB') {
        printf("ERROR: not a .bmp");
        return 1;
    }

    printf("type: %i\nsize: %i\nres1: %i\nres2: %i\noffset: %i\n", file_header.type, file_header.size, file_header.res1, file_header.res2, file_header.offset);
    fclose(fp);

    return 0;
}
#包括
#包括
类型定义结构{
无符号短型;
无符号整数大小;
无符号短res1;
无符号短res2;
无符号整数偏移量;
}BMP_文件_头;
int main(int参数,字符**argv){
char*file_name=argv[1];
文件*fp=fopen(文件名,“rb”);
BMP\u文件\u头文件\u头;
fread(&file_header,sizeof(BMP_file_header),1,fp);
if(file_header.type!=“MB”){
printf(“错误:不是.bmp”);
返回1;
}
printf(“类型:%i\n大小:%i\nres1:%i\nres2:%i\n偏移量:%i\n”,文件头.type,文件头.size,文件头.res1,文件头.res2,文件头.offset);
fclose(fp);
返回0;
}

此处标题为十六进制:

0000000 42 4d 36 00 0c 00 00 00 00 00 36 00 00 00 28 00
0000020 00 00 00 02 00 00 00 02 00 00 01 00 18 00 00 00
长度字段是字节36 00 0c 00`,按英特尔顺序排列;作为32位值处理,它是0x000c0036或十进制786486(与保存的文件大小匹配)


可能您的C编译器正在将每个字段与32位边界对齐。启用包结构选项、pragma或指令。

我可以在您的代码中找到两个错误

第一个错误:您必须将结构打包为1,因此每个类型大小都正好是它的预期大小,因此编译器不会将其对齐(例如4字节对齐)。所以在你的代码中,
short
,它不是2个字节,而是4个字节。其中的诀窍是使用编译器指令打包最近的结构:

#pragma pack(1)

typedef struct {
    unsigned short type;
    unsigned int size;
    unsigned short res1;
    unsigned short res2;
    unsigned int offset;
} BMP_FILE_HEADER;
现在它应该正确对齐

另一个错误在这里:

if (file_header.type != 'MB')
您正在尝试检查
short
类型(2个字节)和
char
类型(使用
'
),后者是1个字节。编译器可能会就此向您发出警告,单引号仅包含1个字符(大小为1字节),这是一个规范

为了解决这个问题,您可以将这2个字节分成2个1字节的字符,这些字符是已知的(
M
B
),然后将它们组合成一个
字。例如:

if (file_header.type != (('M' << 8) | 'B'))

然后你的代码应该可以工作。

确保你的
BMP\u文件头
已打包,即sizeof(BMP\u文件头)=14@Musa是16。谢谢,现在我有事情要做。谢谢。工作起来很有魅力,只是在结构之前添加了
#pragma pack()
if (file_header.type != 0x4D42)