从bmp文件中获取不正确的值

时间:2012-09-25 15:54:39

标签: c image image-processing

  

可能重复:
  How to read a binary file in c? (video, images, or text)

我正在尝试使用C程序读取bmp file的内容。我能够阅读内容,但读取的值与我的预期相矛盾。我的代码是:


FILE *fp=NULL;
fp=fopen("C:\\Users\\Saurabh\\Pictures\\nice.bmp","r");

if(fp!=NULL)
{
    printf("%c\n",fgetc(fp));
    printf("%c\n",fgetc(fp));

    printf("%c\n",fgetc(fp));
    printf("%c\n",fgetc(fp));
    printf("%c\n",fgetc(fp));
    printf("%c\n",fgetc(fp));
}

else
    printf("Error reading the file");

我只是在这里逐字节阅读,只是为了理解。前两个字节读取BM这是正确的。接下来的四个字节读取*t。预期值为40.请参阅format。有人可以解释发生了什么,如果我需要执行一些转换,如何获得值40

2 个答案:

答案 0 :(得分:2)

我相信您的问题是您打开文件的方式:

fp=fopen("C:\\Users\\Saurabh\\Pictures\\nice.bmp","r"); 

“r”用于ASCII读取,您想以二进制打开它:

fp=fopen("C:\\Users\\Saurabh\\Pictures\\nice.bmp","rb"); 

修改 fgetc()返回一个int,所以我尝试使用int来获取返回值,也希望以十六进制的形式看到结果,所以让我们使用十六进制输出格式:

FILE *readf;
int i;
unsigned int size = 0;

//Open file
readf = fopen("blackbuck.bmp", "rb");

i = fgetc(readf);
printf("%#x\n",i);   // 0x42
i = fgetc(readf);
printf("%#x\n",i);   // 0x4D
for(i=0; i<3; i++)
    size |= fgetc(readf) << (i*8); // 0xC0036

此更新将前两个值作为0x42 0x4D,然后合并下一个3个字节,给出位图的大小(0xC0036 = 786486字节)

我使用此图片进行测试:http://people.sc.fsu.edu/~jburkardt/data/bmp/blackbuck.bmp

您可以看到结果具有bmp标头0x42 0x4d的正确字节代码 the header field used to identify the BMP & DIB file is 0x42 0x4D in hexadecimal, same as BM in ASCII

答案 1 :(得分:1)

虽然我同意迈克的意见,你应该以二进制模式阅读这个文件,但它不应该引起你的问题。它最终会,但前6个字符不应该破坏,除非任何大小的字节包含10或13。

为了读取int,您可以执行类似

的操作
int result;
fread(fp, sizeof (int), 1, &result);

但请注意,这不是便携式的。 (它假设32位整数和本机字节顺序,至少。由于它们的起源,BMP是小端的......如果你只是在大的时候一次性读取它,那么大小就会很古怪 - 端机。)

另一种方式:

unsigned long result = 0;
for (int i = 0; i < 4; ++i) {
     result |= (unsigned long) fgetc(fp) << (i * 8);
}

至少应始终读取正确的字节数并考虑字节序。并且unsigned long足以容纳任何32位数字,而int(甚至无符号)则不能保证。