c++ - Win32 C/C++ 从字节数组中读取 BMP 宽度和高度

标签 c++ c winapi bitmap

我已经将一个 BMP 文件读入一个字节数组。所以在查看了这个问题的答案之后:byte array to int c++ .这是从 BMP information header 获取宽度和高度的方法吗?安全正确?

long width, height;
memcpy(&width, &bmp[0x12], sizeof(long)); 
memcpy(&height, &bmp[0x16], sizeof(long));

这种方法会带来什么问题?

long* width = (long*)(&bmp[0x12]);
long* height= (long*)(&bmp[0x16]);

根据 Wikipedia BMP file format , 0x12 是位图宽度的偏移量(以像素为单位),0x16 是位图高度的偏移量(以像素为单位)。

PD。我为 loading the bitmap from memory buffer 找到了这个解决方案但我想保持代码简单,因为我只需要位图的宽度、高度和原始数据,我也不知道这个答案是否安全。

谢谢!

最佳答案

这两种方法基本上做同样的事情,并且都有相同的基本问题:如果主机系统的字节顺序与 BMP 文件使用的字节顺序不同,则无法工作。这始终是直接访问大于二进制格式的单个字节的值的问题。

后一种方法还有一个额外的缺点,即如果主机无法对结果地址进行long 访问,则可能会中断。

简而言之,两种“解决方案”都不好。最好逐字节提取值并重新构造它:

static uint32_t read_uint32_t(const uint8_t *buffer, size_t offset)
{
  buffer += offset;
  const uint32_t b0 = *buffer++;
  const uint32_t b1 = *buffer++;
  const uint32_t b2 = *buffer++;
  const uint32_t b3 = *buffer++;
  return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
}

为简洁起见,上面使用了一小部分 C99,将其移植回 C89 是微不足道的。

编辑:以上适用于任何 架构,因为它不再进行直接访问。相反,它假定 buffer 包含小端格式的字节,我相信这是源自 x86 的 BMP 格式始终使用的格式。因此,它甚至可以在大端机器上运行。它也不再进行可能未对齐的大内存访问,因为所有访问都是字节大小的,这应该可以工作。

关于c++ - Win32 C/C++ 从字节数组中读取 BMP 宽度和高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20075441/

相关文章:

c - C/POSIX 语言环境中扩展字节/字符的行为

c++ - 我想让线程的执行顺序依次执行

c++ - 此 Windows 应用程序使用什么 API/SDK?

c++ - Qt:文件名中的非 ASCII 字符被替换为 '?'

c++ - 尝试学习 C++,Tic Tac Toe 程序不起作用

c++ - 构造函数中的默认参数

检查变量是否为某个值

c++ - 纯虚方法的模板特化

c - 堆栈清理不起作用(__stdcall MASM 函数)

c++ - 如何确定 C++ 控制台应用程序中的当前键盘语言?