【问题标题】:Reading information stored in header array when reading BMP file in c在c中读取BMP文件时读取存储在头数组中的信息
【发布时间】:2021-12-05 11:56:56
【问题描述】:

我正在尝试使用 c 学习图像处理。

#include <stdio.h>

int main(){
    FILE *streamIn;
    streamIn=fopen("lena512.bmp","r");

    //read imageHeader and colorTable
    unsigned char header[54];//to store the image header
    //unsigned char colorTable[1024];//to store the colorTable,if it exists

    for(int i=0;i<54;i++){
            header[i]=getc(streamIn);
    }
    /*
      width of the image(18th byte)
      height of the image(22nd byte)
      bitDepth of the image(28th byte)
    */
    int width=*(int*)(&header[18]);
    int height=*(int*)(&header[22]);
    int bitDepth=*(int*)(&header[28]);


}

我遇到了我无法理解的线路。

int width=*(int*)(&header[18]);

为什么我们不能像int width=(int)(header[18]);? 那样简单地进行类型转换

【问题讨论】:

  • 因为header 被声明为unsigned char (array of)。另外:最好使用官方的 Windows 标头。
  • 澄清一下,(int)&lt;something&gt; 并不意味着将&lt;something&gt; 视为int 引用。相反,它的意思是将&lt;something&gt; 的任何内容转换(int)。在这种情况下,&lt;something&gt;header[18],这是一个 unsigned char 值。所以这将采用那个一个字节的值并将其扩展为int 大小。

标签: c type-conversion bmp bitmapimage unsigned-char


【解决方案1】:

我遇到了我无法理解的线路。
int width=*(int*)(&amp;header[18]);

写它的人也没有,因为这是在几个不同的方面公然未定义的行为。它给出了这给出了一个未对齐的地址(在主流系统上)以及一个严格的别名违规。 What is the strict aliasing rule?

最后那 3 行是 bug,你不能这样写 C 代码。编写此程序的正确方法可能是将数据复制到 OS API 提供的预定义结构中。

【讨论】:

  • (不幸的是,在 Windowswingdi.h 的情况下,位图 API 被设计破坏并依赖于古老的“struct hack”。因此标准 C 编译器无法可靠地使用它......)
【解决方案2】:

您正在使用*(int*)(&amp;header[18]),您想知道为什么不能使用(int)(header[18])

嗯,这些是完全不同的表达方式。

第一个接受header[18]地址,这是一个unsigned char,所以它给出了一个指向它的指针。将其转换为指向 int 的指针并在分配中通过 * 取消引用它会复制一个完整的 int 从该地址开始,读取所有必要的字节。

第二个简单地读取header[18] 中的单个unsigned char 并将 转换为int。这将只使用第一个字节。


注意:Microsoft 的头文件提供了 BMP 头的结构定义。使用它们要好得多。例如,您可以调用fread() 来读取标题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2015-05-15
    • 2018-04-10
    • 2021-07-06
    相关资源
    最近更新 更多