c++如何读取和操作内存中的位图文件头结构【进阶】

老萱小哥_7467

老萱小哥_7467

2026-04-09

739人浏览

原创

bitmapfileheader和bitmapinfoheader必须用#pragma pack(2)保证2字节对齐,否则字段错位;bfoffbits指像素数据起始偏移(含调色板),需按行4字节对齐重算;biheight为负表示top-down存储,读取时须行序反转。

c++如何读取和操作内存中的位图文件头结构【进阶】

BITMAPFILEHEADER 和 BITMAPINFOHEADER 的内存布局必须严格对齐

Windows 位图文件头不是普通结构体,BITMAPFILEHEADER 和 BITMAPINFOHEADER 依赖 #pragma pack(2)(实际是 2 字节对齐),否则直接 memcpy 到结构体会因编译器自动填充导致字段错位。VC++ 默认结构体按 8 或 16 字节对齐,读出来 bfOffBits 可能指向错误位置,后续解析全崩。

实操建议:

  • 用 #pragma pack(push, 2) 包裹结构体定义,读取前确保对齐一致
  • 不要依赖 sizeof(BITMAPFILEHEADER) 做偏移计算——它可能等于 16(对齐后),但真实文件中固定占 14 字节
  • 手动校验:读取前 2 字节是否为 'B' 和 'M',再检查 bfSize 是否与实际文件大小一致,避免误判非 BMP 数据

从内存 buffer 解析时,bfOffBits 是关键分水岭

bfOffBits 不是“图像数据起始偏移”的绝对值,而是从文件开头到 BITMAPINFOHEADER 之后第一个像素字节的距离。如果位图含调色板(如 8bpp),这个值会大于 sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER),差值就是调色板字节数。

常见错误现象:

  • 把 bfOffBits 当作“信息头结束位置”,直接从那里开始读像素,结果跳过调色板,图像颜色全乱
  • 忽略 biCompression:值为 BI_BITFIELDS(3)时,bfOffBits 后面紧跟着 3 个 DWORD 掩码,不是像素数据
  • 没检查 biHeight 符号:负值表示倒序存储(top-down BMP),逐行读取时 Y 方向要反转

修改 biWidth / biHeight 后必须重算 bfSize 和 bfOffBits

单纯改 biWidth 或 biHeight 不影响文件头本身大小,但会改变像素数据总字节数和对齐要求,进而影响 bfSize(整个文件大小)和 bfOffBits(像素起始位置)。尤其当新宽度导致每行字节数变化时,Windows 要求每行必须是 4 字节对齐,所以补零量(padding)会变。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载

计算逻辑:

  • 每行原始字节数 = ((biWidth * biBitCount) + 7) / 8
  • 对齐后行字节数 = ((biWidth * biBitCount) + 31) / 32 * 4
  • bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 调色板字节数
  • bfSize = bfOffBits + 对齐后行字节数 * abs(biHeight)

漏掉 padding 重算,写回内存后用 Windows 看图器打开会提示“无效图像”或直接崩溃。

用 reinterpret_cast 读取像素前先确认 biBitCount 和格式

biBitCount 决定每个像素占多少位,不等于每个像素占多少字节。例如 16bpp 实际是 2 字节,但可能是 5-5-5 或 5-6-5;24bpp 是 3 字节 BGR;32bpp 是 4 字节 BGRA(注意 Alpha 通道是否存在)。直接 reinterpret_cast<uint32_t></uint32_t> 强转 24bpp 数据会越界。

使用场景提醒:

  • 处理 24bpp:用 uint8_t* 按 BGR 顺序逐字节访问,别用整型指针跨读
  • 处理 32bpp:检查 biCompression == BI_RGB 还是 BI_BITFIELDS,后者需结合掩码解包
  • 所有操作前用 IsBadReadPtr()(仅调试)或更安全的边界检查,防止 buffer 长度小于 bfSize 导致读越界

最易被忽略的是:BMP 像素数据在内存中是 bottom-up 存储(除非 biHeight 为负),而多数图像处理库默认 top-down。不翻转行序就直接送进 OpenGL 或 OpenCV,图像是镜像的。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

4274

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

4411

25

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

319

31

css中的padding属性作用
css中的padding属性作用

在CSS中,padding属性用于设置元素的内边距。想了解更多padding的相关内容,可以阅读本专题下面的文章。

2023.12.07

2552

3

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3099

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2678

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1448

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2439

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3250

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习