BMP 的像素行可能从底部或顶部开始。检查有符号高度与文件头,使用方向明确的测试图,并验证转换后的 PNG 和 JPG,不要用手工翻转掩盖解码问题。
BMP → PNG
识别 BMP 的两种像素行方向
Windows 设备无关位图中的像素不一定按照画面从上到下的顺序保存。在常见 BITMAPINFOHEADER 情况下,正高度可以描述自下而上的位图,像素数组从最底部扫描行开始;负高度可以描述自上而下的位图,数组从最顶部扫描行开始。解码器必须读取符号,并把存储行映射到显示坐标。如果实现把所有数组都当成自上而下,转换结果就可能垂直翻转。
准备一张方向无法混淆的源图:上边写 TOP,下边写 BOTTOM,并在一侧放置不对称图形。记录文件头中的宽度、有符号高度、位深和压缩方式,再用多个查看器打开原始 BMP。若只有一个程序翻转,重点排查该解码器;若所有程序都一致,创建程序可能已经把像素顺序写错,或让高度符号与实际行数组不匹配。
- 检查高度的正负号
- 使用不对称方向测试图
- 比较多个 BMP 解码器
高度的符号不仅表示像素高度,还可能传达扫描行方向。
把行顺序与其他方向问题分开
行顺序造成的垂直翻转不同于相机旋转或 Exif Orientation 问题,不应套用 JPEG 的诊断方法。如果文字仍然从左向右可读,只是顶部与底部互换,先检查行顺序。若出现九十度旋转、水平镜像或组合变换,则应追踪采集程序、前一次转换,或显示阶段额外施加的变换。先准确描述现象,能避免在错误的元数据字段上浪费时间。
屏幕捕获 API 或旧程序有时会把 DIB 内存写入 BMP,却让高度符号与行数组方向不一致。修改扩展名或手工翻转最终图像,只能遮住一份文件的症状,不能修复生产路径。记录源应用、中间操作和最终转换器,比较每一步的结果。如果能从同一测试图得到正常与异常文件,就并排检查文件头、像素偏移量和开头几行的数据差异。若故障只在一台设备出现,还应记录解码库、操作系统与应用版本,让其他人员能够复现同一条件。
- 区分翻转与旋转
- 追踪创建和转换的每一步
- 比较正常与异常文件头
同时检查行填充与像素偏移
BMP 扫描行可能为了对齐而包含填充字节。如果解码器按可见像素字节数移动,而不是按包含填充的正确行长度移动,画面通常不只是干净地上下翻转,还可能出现斜向漂移、彩色条带或被截断的行。应核对像素数据偏移、位深、宽度以及计算出的每行字节数。选择不能自然落在存储边界上的宽度,更容易暴露填充计算错误。
调色板和压缩 BMP 还会引入额外条件。一份未压缩 24 位样本成功,并不能证明对所有 BMP 都支持。若生产输入含有 1、4、8 位调色板、16 或 32 位像素、类似透明度的通道或压缩变体,就应按实际类别逐一测试。不要猜测新的头部偏移或直接修改字节;保留源文件,用符合规范的实现重新解码并写出标准结果,通常更安全也更容易审计。如果图像宽度只改变一个像素就出现不同症状,应优先复核扫描行长度和对齐公式。
- 计算含填充的扫描行长度
- 测试不便对齐的图像宽度
- 覆盖实际位深与调色板类型
斜向漂移或彩色错行往往说明填充或偏移错误,不只是行方向相反。
按实际用途比较 PNG 与 JPG 输出
把 BMP 转为 PNG 可以得到无损参照,适合检查方向、锐利边缘和准确颜色。JPG 使用有损压缩,也不含透明通道,因此不适合用来诊断细小文字或边界像素。先用 PNG 确认行顺序与像素是否正确;只有接收端需要时再生成 JPG,并把 JPEG 质量、色度采样以及透明区域如何铺底作为单独问题评估。
让原始 BMP、PNG 和 JPG 以相同显示尺寸并排,比较四角、最顶行、最底行和方向标记。不要只看图像是否站正,还要找缺失行、填充导致的颜色偏移或透明度变化。若转换器自动纠正了格式不一致的源文件,应明确记录,因为其他工具仍可能用不同方式解释同一源文件,即使第一次输出看起来完全正常。同时用百分之百缩放检查边缘像素,再按实际展示尺寸判断整体效果。
- 用 PNG 作为诊断参照
- 比较第一行与最后一行
- 记录任何自动修正
在完整交付流程中批准代表性 BMP
建立包含自上而下、自下而上、多种宽度、调色板图像以及生产所用 24 或 32 位类型的测试集。通过实际 BMP 转 PNG 或 BMP 转 JPG 工具处理每个文件,再在目标应用与独立查看器中打开结果。确认上下方向、尺寸、颜色、透明度处理和边缘行完整。为文件使用新名称并保存校验值,避免缓存展示旧结果。对于批量流程,还应抽查第一份、中间一份和最后一份输出,确认任务切换或内存复用没有让后续文件继承错误的行状态。把每类样本的预期方向写入测试记录,并由另一名审核者独立核对,可减少仅凭记忆判断造成的误报。
记录原始文件头、创建应用、转换器版本、输出设置与测试环境。不要把失败的派生图翻转后覆盖保存,应返回源文件并正确解码。最后把方向测试图和真实业务图上传到实际交付服务,下载服务生成或传回的版本,逐行比较边缘与方向。还要保存输入输出校验值,确认审核的确是本次转换结果,而不是缓存中的旧文件。若交付服务再次缩放或转码,应把它产生的预览和原尺寸版本分别作为新输出检查。只有所有必需的 BMP 类别都通过,才开始文件夹级批量转换。
- 测试两种行方向
- 避免陈旧预览缓存
- 检查下载后的交付文件
方向测试图和真实业务 BMP 都通过后,才能开始批量转换。
要点总结
- 在常见 DIB 结构中,正高度可能表示自下而上的行,负高度可能表示自上而下的行。
- 忽略高度正负号的解码器会把图像上下翻转,或让不同应用得到不一致的结果。
- 使用明显不对称并标出上下的样本,同时检查文件头,可把行顺序故障与旋转或采集问题区分开。
- 转换后应在真实接收系统中检查方向、尺寸、颜色、行填充以及顶部和底部边缘。
常见问题
为什么 BMP 可以先保存最底部一行?
传统 DIB 布局可以用正高度表示自下而上的数组,由解码器在显示时重建为从上到下的视觉顺序。
BMP 高度为负数一定说明文件损坏吗?
不一定。在支持的文件头结构中,负高度可以有意表示自上而下的位图。
能否只在编辑器里把转换结果上下翻转?
这样可能修好一个可见文件,却会留下解码器或源文件的不一致,后续文件仍可能再次失败。
图像斜向错位也是行顺序问题吗?
更常见的原因是扫描行填充长度或像素偏移计算错误,应结合宽度和位深检查。
最终转换检查应该做什么?
转换方向标记图和真实 BMP,并在实际下载的交付文件中比较方向、边缘行、尺寸和颜色。