博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BMP位图文件格式分析
阅读量:6074 次
发布时间:2019-06-20

本文共 2253 字,大约阅读时间需要 7 分钟。

使用画图工具(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字节*/
 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
,如需转载请自行联系原作者
你可能感兴趣的文章
仿射变换详解 warpAffine
查看>>
字符串的属性和方法的调用
查看>>
Genymotion虚拟机启动时get no IP address的解决方法汇总
查看>>
HTML5之tabindex属性
查看>>
分页查询和redis
查看>>
windwos下开发的php上传至linux服务器下需要注意些什么问题?
查看>>
排序算法总结(四)快速排序【QUICK SORT】
查看>>
adb安装启动Touch校正软件
查看>>
内存泄漏的分析?
查看>>
[WinCE] [Win10] Win10 Creator 升级后 Windows Mobile Device Center 不能打开
查看>>
模拟spi如何写
查看>>
configparser配置文件模块
查看>>
POJ 3295:Tautology
查看>>
(转载)浅谈C#中的泛型
查看>>
Robotlegs一个基于puremvc的框架
查看>>
unity射线碰撞检测+LayerMask的使用
查看>>
[转]字符集编码常识
查看>>
【BZOJ1305】【CQOI2009】 dance跳舞
查看>>
Copy 方法 和 ostream 迭代器
查看>>
层中层事件问题
查看>>