【问题标题】:Getting wrong data while reading Bitmap image读取位图图像时获取错误数据
【发布时间】:2012-05-02 16:06:16
【问题描述】:

我正在学习本教程 http://www.gamedev.net/page/resources/_/technical/game-programming/how-to-load-a-bitmap-r1966 我加载的所有位图标题/信息的值都错误。

我已经声明了存储位图头信息的结构

typedef struct BITMAPFILE_HEADER {
  WORD  bfType;
  DWORD   bfSize;
  WORD  bfReserved1;
  WORD  bfReserved2;
  DWORD   bfOffBits;
} BITMAPFILE_HEADER;

//Bitmap information header
//provides information specific to the image data
typedef struct BITMAPINFO_HEADER{
  DWORD  biSize;
  LONG   biWidth;
  LONG   biHeight;
  WORD   biPlanes;
  WORD   biBitCount;
  DWORD  biCompression;
  DWORD  biSizeImage;
  LONG   biXPelsPerMeter;
  LONG   biYPelsPerMeter;
  DWORD  biClrUsed;
  DWORD  biClrImportant;
} BITMAPINFO_HEADER;

//Colour palette
typedef struct RGB_QUAD {
  BYTE  rgbBlue;
  BYTE  rgbGreen;
  BYTE  rgbRed;
  BYTE  rgbReserved;
} RGB_QUAD;

之后我使用以下代码读取位图:

    FILE *in;
    in = fopen("picture.bmp", "rb");

    if (in == NULL)
    {
        printf("Error opening file\n");
    }
    else
    {
        BITMAPFILE_HEADER bmfh;
        BITMAPINFO_HEADER bmih;

        fread(&bmfh, sizeof(BITMAPFILE_HEADER), 1, in);
        fread(&bmih, sizeof(BITMAPINFO_HEADER), 1, in);

        if (bmih.biBitCount != 24)
            printf("not 24");
    }

我的图片是 24 位的,但是当我运行这个程序时,它显示“不是 24”。我尝试在 Visual Studio 中调试它,然后我看到 bmih.biBitCount0。另外,图片的宽度和高度也是错误的,我在标题中找到的唯一正确数据是bmfh.bfType,即19778

有人知道我的代码有什么问题吗? 同样,我只想读取 bmp 但不显示它。

PS: 最初的图片是JPEG格式。我使用 MS PAINT 将其转换为 BMP 格式并以 BMP 格式重新保存。我想知道它会影响价值观吗?

【问题讨论】:

  • 宽度和高度应该是多少,代码说的是什么?代码报告的位数是多少?
  • 位图有不同的版本。我不确定油漆使用的是什么版本,但您可能想检查它是否相同。我知道存在差异,因为我编写了一个可以读/写版本 3 但许多文件是 6 并且无法读取的文件。
  • 图像分辨率为1024 x 768,但读取BMP后得到的值为width=50331648 height=65536 bitcount=0 planes=24
  • 链接的文章提到结构已经定义并且可以包含在“#include ”中。由于您使用的是 Visual Studio,是否有理由自己声明这些结构?
  • 感谢 stefaanv,再次指出我的错误。是的,在使用了windows.h中已经定义好的结构后,效果很好!

标签: c++ graphics


【解决方案1】:

我想你遇到了alignment issue,因为编译器可以选择在他认为合适的结构中对齐数据。您可以尝试打包您的结构,但我建议将每个字段都读出并单独填写,这样工作量更大,但更清晰,并且避免了对齐问题。

【讨论】:

  • fread(&bmfh.bftype, sizeof(bmfh.bftype), 1, in);fread(&bmfh.bfsize, sizeof(bmfh.bfsize), 1, in);...,有检查返回值。
  • 哇,它就像一个魅力!无论如何,我想知道 filestreamer 如何区分哪个存储在哪个变量中?我们只需指定 sizeof 然后它就会知道把@@放在哪里?
  • 哦,我注意到我阅读标题的顺序非常重要。
猜你喜欢
  • 2016-04-05
  • 2020-09-01
  • 2011-10-21
  • 2017-08-16
  • 2021-11-14
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多