【问题标题】:I can't reach the size of header of BMP file in c code我无法在 C 代码中达到 BMP 文件头的大小
【发布时间】:2020-06-21 14:23:13
【问题描述】:

我想复制一个 1 位 BMP 图像,我写了这段代码。我不知道为什么我的代码中 Header 结构的大小是 56,虽然它必须是 54。

我的 struct HeaderBMP 代码:



      short _type;    // file type
      short _size;
    int _reserved;
       int _offset;

        int  _info_size;
        int _width;
        int _height;

        short _planes;
        short _bpp;

        int _compression;
        int _imagesize;

        int _xresolution;
        int _yresolution;

        int _colours;
        int _impcolours;


我无法达到 54 号,当我尝试修复时它只是 52 或 56 号。我希望你能帮我解决这个问题。

【问题讨论】:

  • 不要在局部变量名上使用前导下划线。编译器在创建汇编代码时,会在所有名称上插入前导下划线,本地标签除外。
  • 根据format of .bmp file,文件大小字段是 4 个字节,而不是 2 个字节。可能还有其他问题,但这应该可以帮助您朝着正确的方向开始。
  • 根据底层硬件,int 可能是 2 或 4 或 8 个字节。最好使用来自stdint.h 的类型或将每个字段定义为char 的数组并根据需要执行隐式转换

标签: c bmp


【解决方案1】:

对这种结构使用固定大小的整数。这些类型在stdint.h 头文件中定义。 struct 可能需要打包(由实现定义)

gcc 示例:

typedef struct {             // Total: 54 bytes
  uint16_t  type;             // Magic identifier: 0x4d42
  uint32_t  size;             // File size in bytes
  uint16_t  reserved1;        // Not used
  uint16_t  reserved2;        // Not used
  uint32_t  offset;           // Offset to image data in bytes from beginning of file (54 bytes)
  uint32_t  dib_header_size;  // DIB Header size in bytes (40 bytes)
  int32_t   width_px;         // Width of the image
  int32_t   height_px;        // Height of image
  uint16_t  num_planes;       // Number of color planes
  uint16_t  bits_per_pixel;   // Bits per pixel
  uint32_t  compression;      // Compression type
  uint32_t  image_size_bytes; // Image size in bytes
  int32_t   x_resolution_ppm; // Pixels per meter
  int32_t   y_resolution_ppm; // Pixels per meter
  uint32_t  num_colors;       // Number of colors  
  uint32_t  important_colors; // Important colors 
} __attribute__((packed)) BMPHeader;

【讨论】:

  • 关于:struct 可能需要在磁盘上打包(由实现定义),.bmp 文件始终是“打包”的,
  • 关于:typedef struct { 如果没有“标签”名称,大多数调试器将无法显示结构中的各个字段。
  • @user3629249 谁告诉你的?¿ 我多年来一直使用 gdb 调试这样的结构,没有任何问题
  • 我已经进行了将近 50 年的编程,(从我们通过钉板上的跳线进行编程的时代开始。)gdb 调试器是一款出色的调试器,包含很多便利大多数调试器都没有。然而,并不是每个人都在使用gdb,尤其是那些使用基于微软的调试器的人。
  • @user3629249 磁盘上没有结构。可执行代码中没有结构。它们仅在 C 源代码中。
【解决方案2】:

感谢您的解决方案,但是当我在窗口 10 x64 上通过 cmd 传递参数进行编译时,它也是 56。当它在 ubuntu 和窗口上的代码块上工作时,它是 54,并在代码中传递参数。 我的解决方案:

typedef struct {             // Total: 54 bytes
   char  _type[2];             // Magic identifier: 0x4d42
  char  _size[4];             // File size in bytes
  char _reserved1[2];        // Not used
  char  _reserved2[2];        // Not used
  char _offset[4];           // Offset to image data in bytes from beginning of file (54 bytes)
  char  _dib_header_size[4];  // DIB Header size in bytes (40 bytes)
  char   _width[4];         // Width of the image
  char   _height[4];        // Height of image
  char _planes[2];       // Number of color planes
  char  _bpp[2];   // Bits per pixel
  char _compression[4];      // Compression type
  char  _image_size[4]; // Image size in bytes
  char   _x_resolution_ppm[4]; // Pixels per meter
  char   _y_resolution_ppm[4]; // Pixels per meter
  char _num_colors[4];       // Number of colors
  char  _important_colors[4]; // Important colors
}  header;

当我需要取值时,我会这样做:

    *(int*) header._width

我测试过,它适用于以上三种情况。

【讨论】:

  • 作为旁注:变量名的前导下划线是为实现“保留”的。强烈建议不要使用前导下划线
猜你喜欢
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
相关资源
最近更新 更多