C++如何读取和保存BMP格式图片_C++纯代码实现图像二进制读写【图形】-C++

直接用 fread 读 BMP 文件头会出错,必须先校验文件签名“BM”(0x4D42),再按 bfOffBits 跳转、处理行对齐与上下颠倒、BGR 顺序及小端存储,否则易导致花屏或无法加载。

直接用 fread 读 BMP 文件头会出错?先校验文件签名

BMP 文件开头必须是 "BM" 两个字节,否则不是合法 BMP。很多代码直接 fread 结构体就跑,结果读到损坏或非 BMP 文件时内存错乱。

  • 打开文件后立刻用 fread(&signature, 1, 2, fp) 读前两字节,检查是否等于 0x4D42(小端序下 'B' 在低字节)
  • BITMAPFILEHEADER 固定 14 字节,但 bfOffBits 字段决定像素数据起始位置,不能硬编码跳过 54 字节——因为可能有调色板、压缩或对齐填充
  • 若 biCompression != BI_RGB(比如 BI_RLE8),标准 RGB 读取逻辑会失败,应直接拒绝处理

读取像素数据时注意 Windows BMP 的行对齐和上下颠倒

Windows BMP 每行字节数必须是 4 的倍数,不足则补 0;且图像数据从底行开始存储(即第 0 行是图片最下面一行),不翻转会导致图倒过来。

  • 计算每行实际字节数:rowSize = ((width * bitsPerPixel + 31) / 32) * 4
  • 分配缓冲区大小为 rowSize * height,再用 fread 一次性读入
  • 逐行复制到目标图像数组时,把第 i 行写入目标的 height - 1 - i 行,完成上下翻转
  • 如果只处理 24 位真彩色(bitsPerPixel == 24),每个像素 BGR 顺序(不是 RGB),需手动交换 R 和 B

保存 BMP 时别漏掉 bfSize 和 biSizeImage 的正确计算

这两个字段填错,系统可能拒绝加载或显示为全黑——它们不是可选字段,而是解析器判断数据长度的关键依据。

  • bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paletteSize + pixelDataSize,其中 paletteSize 对 24 位图是 0
  • biSizeImage = rowSize * height(注意不是 width * height * 3,要含补齐字节)
  • 写入顺序必须严格为:BITMAPFILEHEADER → BITMAPINFOHEADER → 调色板(如有)→ 像素数据(从底行开始、BGR 顺序)
  • 写像素数据前记得把内存中的 RGB 图像先转成 BGR,并按行倒序排列

没有第三方库时,std::ifstream 比 fopen 更安全但要注意二进制模式

用 C++ 流操作容易在 Windows 下因换行符转换出问题,尤其读写二进制图像数据时。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » C++如何读取和保存BMP格式图片_C++纯代码实现图像二进制读写【图形】-C++
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4000915+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4000915+
  • 本周更新: 0+
  • 最后更新: 2026-03-16