BMP位图文件格式分析

简介:
使用画图工具(ms+R调出运行框,输入mspaint即可)分别存储2个文件
1.bmp(400*300px),2.bmp(200*150px)白画布。

使用Beyond Compare比较下2个文件数据,注意使用Hex16进制方式。

前2个字节42 4D对应字符BM,是文件类型,这里表示ms的bmp文件类型
紧着的4个字节是文件字节数,F6 D8 01 00==》1.bmp
应为存储方式是高位字在高地址的方式存储,所以
实际是0001D8F6==>转成10进制数值是121078字节=》除以1024就是118K,自己核对下文件属性看看文件大小是不是118k;
而2.bmp文件的是66 79 00 00
对应00007966=>31078字节=》30.3k

随后的4个字节全为00,系统保留。

再后面的4个字节代表的是实际的图像数据开始的位置(偏移量)
这里都是36 04 00 00
也就是00000436H,在Beyond Compare里Ctrl+G,选择Hex,16进制方式,输入
0436转到该位置发现文件数据全是FF也就是白色:




然后在看下windows定义的bmp文件头结构体定义就更清晰了:
typedef struct tagBITMAPFILEHEADER 
{  
UINT16 bfType;  /*bmp文件类型-占2字节*/  
DWORD bfSize; /*bmp文件大小-占4字节*/
UINT16 bfReserved1; /*保留-占2字节*/
UINT16 bfReserved2; /*保留-占2字节*/
DWORD bfOffBits;  /*位图数据偏移-占4字节*/
} BITMAPFILEHEADER; 

共14个字节。

文件头后面是文件信息头部,主要是位图文件的详细信息,windows定义的文件信息头的结构体如下:
typedef struct    tagBITMAPINFOHEADER
{
DWORD biSize; /*文件信息头占的字节大小-该字段占4字节*/
LONG biWidth; /*宽度4字节*/
LONG biHeight; /*高度4字节*/
WORD biPlanes; /*颜色平面数2字节, 总是1(文章1.bmp,2.bmp里可以看到01 00这2个字节)*/
WORD biBitCount; /*每个图像像素所占比特数,占2字节,我们这里是8bit,256种颜色,呵呵*/
DWORD biCompression; /*图像数据压缩类型4字节*/
DWORD biSizeImage; /*图像大小4字节*/
LONG biXPelsPerMeter; /*水平分辨率4字节*/
LONG biYPelsPerMeter; /*垂直分辨率4字节*/
DWORD biClrUsed; /*所使用颜色表索引数4字节*/
DWORD biClrImportant; /*对图像重要影响的索引数4字节占据*/
} BITMAPINFOHEADER;

统计下:4+4+4+2+2+4+4+4+4+4+4=40共40个字节,验证。

我们的位图里是00 00 00 28==>十进制就是40个字节,文件信息头占40字节;
紧接着后面
(注明:那个空白应该是Beyond Compare比对文件产生的,跳过,只看有字符数据的部分)
1.bmp图像尺寸:
biWidth字段:
90 01 00 00=>逆转下顺序 0x00000190=>400px
biHeight字段:
2C 01 00 00=>0x0000012C=>300px

同理2.bmp图像尺寸:
biWidth字段:
C8 00 00 00=>逆转下顺序 0x000000C8=>200px
biHeight字段:
96 00 00 00=>0x00000096=>150px

接着看:
01 00==>位图平面数,总是为1
08 00==》位图位数8位图像(00 08),一个像素占1个字节。
00 00 00 00==》压缩类型,0 不压缩
图像大小:
1.bmp=>C0 D4 01 00 ==>0x0001D4C0 ==>120000
验证400*300=120000  正确。


2.bmp=>30 75 00 00 ==>0x7530 ==>30000
验证200*150=30000  正确。

其他几个字节就不看了。

从第54个字节开始是一张颜色索引表
每4个字节代表一种颜色,形式如下
(蓝,绿,红,Alpha)就是(B,G,R,A)
可以看到:
00 00 00 00=(00,00,00,00)==黑色
00 00 80 00=(00,00,80,00)===红色
00,80,00,00=(00,80,00,00)==绿色
.....
256个颜色就是
256*4=1024个字节,也就是说位图文件除去真正的像素数据,光文件头之类的信息就是14+40+1024=1078个字节大小

根据前面的文件头提到的偏移
00000436H==1078
正好吻合。
ctrl+G,转到1078开始的部分就是图像的数据信息。

数据存储是从图像左下角到右上角,按行存储,即先存储最后一行的第一个像素,其次第二个,依次类推。



 本文转自 xcf007 51CTO博客,原文链接:http://blog.51cto.com/xcf007/314808 ,如需转载请自行联系原作者
相关文章
|
存储 自然语言处理 程序员
探究C/C++编码世界:从字符编码到中文处理之艺(一)
探究C/C++编码世界:从字符编码到中文处理之艺
314 1
|
数据采集 机器学习/深度学习 自然语言处理
Masked Language Modeling,MLM
Masked Language Modeling(MLM)是一种预训练语言模型的方法,通过在输入文本中随机掩盖一些单词或标记,并要求模型预测这些掩盖的单词或标记。MLM 的主要目的是训练模型来学习上下文信息,以便在预测掩盖的单词或标记时提高准确性。
952 1
|
数据可视化 数据挖掘 Python
【数据分析与可视化】Matplotlib中动态rc参数设置详解与实战(图文解释 附源码)
【数据分析与可视化】Matplotlib中动态rc参数设置详解与实战(图文解释 附源码)
662 0
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
577 0
|
10月前
|
Unix Linux Docker
CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局
操作系统是计算机系统的核心软件,管理和控制硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。Linux作为开源、跨平台的操作系统,具有高度可定制性、稳定性和安全性,广泛应用于服务器、云计算、物联网等领域。其发展得益于庞大的社区支持,多种发行版如Ubuntu、Debian、Fedora等满足不同需求。
279 5
|
C语言
C 语言文件处理全攻略:创建、写入、追加操作解析
在 C 语言中,您可以通过声明类型为 FILE 的指针,并使用 fopen() 函数来创建、打开、读取和写入文件:
415 0
|
监控 Python
`pytest-qt` 是一个用于在 Qt 应用程序中进行 GUI 测试的 pytest 插件。
`pytest-qt` 是一个用于在 Qt 应用程序中进行 GUI 测试的 pytest 插件。
|
弹性计算 安全 Shell
【阿里云弹性计算】阿里云ECS安全加固:从访问控制到数据保护的全方位策略
【5月更文挑战第22天】本文详述了阿里云ECS的安全加固策略,包括访问控制(如安全组设置和密钥对管理)、系统安全加固(如安全补丁更新和防病毒措施)以及数据保护(如数据备份、恢复和加密)。通过这些措施,用户可增强ECS安全性,保障业务安全稳定运行。
369 0
|
开发框架 人工智能 前端开发
【GitHub】github学生认证,在vscode中使用copilot的教程
【GitHub】github学生认证,在vscode中使用copilot的教程
2912 4
|
存储 Android开发
详细解读Android获取已安装应用信息(图标,名称,版本号,包)
详细解读Android获取已安装应用信息(图标,名称,版本号,包)
457 0