在 C 中读取 bmp 标头

Posted

技术标签:

【中文标题】在 C 中读取 bmp 标头【英文标题】:reading a bmp header in C 【发布时间】:2015-11-23 21:38:57 【问题描述】:

我编写了一个程序来读取 BMP 文件头。 代码如下:

#include <stdio.h>

typedef unsigned short WORD;
typedef unsigned short BYTE;
typedef unsigned int DWORD;

typedef struct _WinBMPFileHeader 
  WORD   FileType;
  DWORD  FileSize;
  WORD   Reserved1;
  WORD   Reserved2;
  DWORD  BitmapOffset;
 WINBMPFILEHEADER;

int main(int argc, char* argv[]) 

  WINBMPFILEHEADER *header = NULL;
  FILE *fptr;
  size_t bytes_read;

  if (argc == 2) 
    fptr = fopen(argv[1], "r");
    bytes_read = fread(header, sizeof(WINBMPFILEHEADER), 1, fptr);
  
  else
    printf("The number of parameters is wrong.\n");

  return 0;


当我运行程序时,由于 fread 出现分段错误。 这个故障的原因是什么?

【问题讨论】:

您只是假设文件已正确打开。永远不要假设外部资源会成功。如果 fopen() 失败,则返回 null。如果您随后尝试将该 null 用作文件指针,则会出现分段错误。 fread 读取二进制流,但您的 fopen 确实说 'r' 而不是 'rb'。另外,您在尝试打开文件后不检查错误,那么您如何知道文件实际上已成功打开并准备好读取? 可能是这个的副本:***.com/questions/19745658/c-reading-bmp-files 我知道程序在那时失败了,因为我检查了 printf 但我省略了它们只是为了节省空间。此外,gdb 还告诉您问题出在 fread 中。最后,我只是尝试使用 fopen(argv[1], "rb") 并再次失败。 【参考方案1】:

看看这个

WINBMPFILEHEADER *header = NULL;
...
bytes_read = fread(header, sizeof(WINBMPFILEHEADER), 1, fptr);

分段错误是因为您将NULL 传递给函数。你必须为header分配内存,也许

header = malloc (sizeof(WINBMPFILEHEADER));

您还有一个声明错误作为单独的问题:

typedef unsigned short BYTE;

应该是

typedef unsigned char BYTE;

最后,您必须确保没有任何 2 或 4(我认为没有任何 8)字节字段的 endian 问题,这有点离题了。

【讨论】:

谢谢,现在可以了。我对声明有疑问。为什么是“typedef unsigned short BYTE;”正确的声明? 如果这个答案是正确的,请“接受”它。至于您的评论问题,这是一个“错字”或“复制/意大利面”错误。为什么要将两种类型定义为相同?查看上面的 WORD typedef。 BYTE 永远不会是short 我想你的意思是“为什么typedef unsigned short BYTE; 错误声明?”【参考方案2】:

试试这个,这是我用的一个简单的

synHead reader(FILE* img)  
synHead info;
fseek(img, 10, 0);
fread(&info.D, 1, 4, img);

fseek(img, 18, 0);
fread(&info.W, 1, 4, img);

fseek(img, 22, 0);
fread(&info.H, 1, 4, img);

return(info);

【讨论】:

以上是关于在 C 中读取 bmp 标头的主要内容,如果未能解决你的问题,请参考以下文章

读取 BMP 文件 C++(读取 BMP 标头时出现问题)

读取 BMP 标头,打包。读取不正确的值

C ++:读取位图图像的问题

如何在c语言 读取BMP图片的信息

从 bmp 文件的头部读取

使用 fread() 读取 BMP 的文件头