全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

c++如何操作二进制位图文件BMP_c++ 文件头解析与像素数据读写【实战】

C++读取BMP需先校验文件头:bfType必须为0x4D42("BM"),bfOffBits≥头大小且不超文件长,biBitCount限1/4/8/16/24/32;像素数据自下而上存储、每行4字节对齐、BGR顺序。

如何用 C++ 读取 BMP 文件头并验证有效性

直接读取 BMP 文件前,必须先校验文件头是否合法,否则后续解析会崩溃或读错数据。关键不是“能不能读”,而是“读到的到底是不是真 BMP”。

  • BITMAPFILEHEADER 前两个字节必须是 0x42 0x4D(即 ASCII "BM"),否则直接返回错误
  • bfOffBits 字段决定像素数据起始位置,它必须 ≥ sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER),且不能超过文件大小
  • BITMAPINFOHEADER::biBitCount 必须是 1、4、8、16、24 或 32,其他值(如 15、30)虽在某些 Windows 版本中被容忍,但标准不支持,fread 后可能解码错乱
  • 注意字节序:BMP 是小端(little-endian),Windows 系统上结构体直接 fread 可用,但跨平台时需手动翻转字段(如 biWidthbiHeight
FILE* fp = fopen("test.bmp", "rb");
if (!fp) { /* 错误处理 */ }

BITMAPFILEHEADER bmfh; fread(&bmfh, sizeof(bmfh), 1, fp); if (bmfh.bfType != 0x4D42) { // 'M' 'B',注意小端存储顺序 fclose(fp); return -1; }

为什么读出的像素数据上下颠倒、每行末尾有填充字节

BMP 的像素数据从图像左下角开始存储,逐行向上,且每行字节数必须是 4 的倍数——这是 Windows GDI 的硬性要求,不是可选行为。

  • biHeight 为正数表示“自下而上”存储;为负数表示“自上而下”(Windows NT+ 支持,但多数生成器仍用正值)
  • 每行像素字节数 = ((biWidth * biBitCount + 31) / 32) * 4,即向上对齐到 4 字节边界;原始宽度字节数不足时,末尾补 0x00
  • 如果你按 biWidth * 3 直接读 24 位图,遇到宽度为 101 像素时就会越界(实际每行占 304 字节,而非 303)
  • 图像显示颠倒,是因为你把第 0 行当成了顶部,而它其实是底部;修复方式是按 biHeight 倒序拷贝行,或修改渲染逻辑

如何安全读写 24 位真彩色 BMP 的 RGB 像素

24 位 BMP 最常见,但操作时最容易因对齐和顺序栽跟头。不要假设内存布局和磁盘布局一致。

  • 计算每行真实字节数:rowSize = ((width * 24 + 31) / 32) * 4,别用 width * 3
  • 分配缓冲区时,按 rowSize * abs(height) 分配,而不是 width * height * 3
  • 读取时用 fseek(fp, bmfh.bfOffBits, SEEK_SET) 跳过头,再逐行 fread(lineBuffer, 1, rowSize, fp)
  • 写入时,每行写完后若 rowSize > width * 3,需补 0 到末尾(可用 memset 填充)
  • 注意:BMP 存储顺序是 BGR(不是 RGB),即每个像素三字节为 bluegreenred;直接丢给 OpenGL / SDL 显示前必须交换 R/B
int width = bi.biWidth;
int height = bi.biHeight;
int rowSize = ((width * 24 + 31) / 32) * 4;
std::vector pixelData(rowSize * abs(height));

fseek(fp, bmfh.bfOffBits, SEEK_SET); for (int i = 0; i < abs(height); ++i) { int srcRow = (height > 0) ? (abs(height) - 1 - i) : i; // 自下而上 → 自上而下 fread(pixelData.data() + srcRow * rowSize, 1, rowSize, fp); }

写 BMP 时最容易漏掉的三个字段校验点

手动生成 BMP 文件头时,90% 的失败源于这三个字段没算准,导致系统拒绝打开或显示为黑图。

  • bfSize 必须等于整个文件字节数:即 sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pixelDataSize,少 1 字节都不行
  • biSizeImage 必须等于 rowSize * abs(height);设为 0 在部分旧工具中会被忽略,但新版本(如 Windows 10 Photo App)会直接报“损坏的图像”
  • bfOffBits 必须等于 sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)(无调色板时);若有调色板(如 8 位图),还要加上调色板字节数(256 * sizeof(RGBQUAD)

这些字段之间强耦合,改一个就得重算另外两个。建议封装成函数,传入 width/height/bits,自动填全。


# windows  # app  # 字节  # 工具  # c++  # win  # 为什么  # red  # 封装  # 结构体  # ASCII  # 自下而上  # 自上而下  # 最容易  # 这是  # 如果你  # 是因为  # 成了  # 设为  # 就得  # 不支持 


相关文章: 文字头像制作网站推荐软件,醒图能自动配文字吗?  详解jQuery停止动画——stop()方法的使用  网站制作公司排行榜,四大门户网站排名?  无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?  平台云上自助建站如何快速打造专业网站?  微信网站制作公司有哪些,民生银行办理公司开户怎么在微信网页上查询进度?  如何高效配置IIS服务器搭建网站?  北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?  如何配置WinSCP新建站点的密钥验证步骤?  佛山网站制作系统,佛山企业变更地址网上办理步骤?  网站制作话术技巧,网站推广做的好怎么话术?  已有域名和空间,如何快速搭建网站?  ,sp开头的版面叫什么?  深圳网站制作平台,深圳市做网站好的公司有哪些?  如何快速建站并高效导出源代码?  寿县云建站:智能SEO优化与多行业模板快速上线指南  如何快速生成专业多端适配建站电话?  建站之星后台管理:高效配置与模板优化提升用户体验  建站之家VIP精选网站模板与SEO优化教程整合指南  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  php json中文编码为null的解决办法  如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  seo网站制作优化,网站SEO优化步骤有哪些?  c# 在ASP.NET Core中管理和取消后台任务  宝塔建站无法访问?如何排查配置与端口问题?  c# Task.ConfigureAwait(true) 在什么场景下是必须的  北京建设网站制作公司,北京古代建筑博物馆预约官网?  c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?  宝塔建站助手安装配置与建站模板使用全流程解析  如何设计高效校园网站?  网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  如何在建站之星网店版论坛获取技术支持?  建站主机默认首页配置指南:核心功能与访问路径优化  建站之星下载版如何获取与安装?  用v-html解决Vue.js渲染中html标签不被解析的问题  c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】  Python文件管理规范_工程实践说明【指导】  建站之星会员如何解锁更多建站功能?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  长沙企业网站制作哪家好,长沙水业集团官方网站?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  如何通过虚拟机搭建网站?详细步骤解析  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  如何在Golang中处理模块冲突_解决依赖版本不兼容问题  微课制作网站有哪些,微课网怎么进?  建站主机CVM配置优化、SEO策略与性能提升指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。