`
wojiaolongyinong
  • 浏览: 72787 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

三分钟解析24位真彩BMP格式文件

阅读更多

三分钟解析24位真彩BMP格式文件

 

         BMP是英语BitMap(位图)的缩写,是Windows系统中的标准图像文件格式,而且文件几乎没有压缩,因此信息完全。不说废话,关于BMP的解释网上一搜一大堆,我们直奔主题,分析如何三分钟解析24位真彩BMP文件。

     首先,需要知道BMP文件里面的字节数据有四个部分,分别是:位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)、定义位图的字节(即位图数据Data Body)阵列

     但是对于我们现在要讨论的24位真彩的BMP文件来说,里面不存在彩色表,因此整个里面只剩下三个部分。

     下来对照着一个实例说明这三个部分(里面没有彩色表,因为是24位真彩图):



 

 

    如上图所示,是一个24位真彩图的字节数据(使用的UltraEdit打开)的开始部分截图(里面的数据均为16进制,即每两个数字代表一个字节),表上面的顶栏0~f 和左侧的000000XX0h 是用来方面看数据的(也可以方便记数),比如数据表的第一行的第三个字节数据9E的位置就是00000000h + 2 = 00000002h ,这就是为什么在一些解释中定位中使用000000XXXh的原因。

 

    我们可以看到数据表被三种颜色的线条划分为16个部分:

 

               1~4部分(红色线划分)是位图文件头;

 

               5~15部分(开始用蓝色线条划分部分)是位图信息头;

 

               16部分(既就是用绿色线划分的后面所有数据)是位图的字节阵列;

 

    如上所说,因为是24位真彩图,所以不存在彩色表。下来详细说明每一部分代表什么含义:

 

   (首先在这里强调一下!!!!在上图中的字节数据中,拿第二部分表示文件大小的字节数据(9E 40 09 00)来说,其16进制真正的顺序和上面显示的是相反的,即就是上图表示的文件大小为0009409E(用16进制表示),因此在读取文件数据操作时,就就需要注意了!!!!)

 

1~4部分(位图文件头):

 

     1:     42 4D 这是BMP文件的标示,是ASCIIBM16进制的值;(大小:2 byte

 

     2 9E 40 09 00 用字节表示的整个文件的大小;(大小:4 byte = 1 dword

 

     3 00 00 00 00 保留,设置为0;(大小:4 byte = 1 dword

 

     4 36 00 00 00 从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量;(大小:4 byte = 1 dword

 

5~15部分(位图信息头):

 

     5 28 00 00 00 位图信息头(Bitmap Info Header)的长度;(大小:4 byte = 1 dword

 

     6 F7 01 00 00 位图的宽度,以像素为单位;(大小:4 byte = 1 dword )(它的16进制大小应反过来,所以10进制大小是503

 

     7 91 01 00 00 位图的高度,以像素为单位;(大小:4 byte = 1 dword

 

     8 01 00  位图的位面数;(大小:2 byte = 1 word

 

     9 18 00 每个像素的位数;(大小:2 byte = 1 word

 

    10 00 00 00 00 压缩说明(0表示不压缩)(大小:4 byte = 1 dword

 

    1168 40 09 00 用字节数表示的位图数据的大小。该数必须是4的倍数(至于为什么下面会有解释)(大小:4 byte = 1 dword

 

    12 C4 0E 00 00 用像素/米表示的水平分辨率;(大小:4 byte = 1 dword

 

    13C4 0E 00 00 用像素/米表示的垂直分辨率;(大小:4 byte = 1 dword

 

    14: 00 00 00 00 位图使用的颜色数;(大小:4 byte = 1 dword

 

    1500 00 00 00 指定重要的颜色数。当该域的值等于颜色数时,表示所有颜色都一样重要;(大小:4 byte = 1 dword

 

16部分(位图字节阵列):

 

     16:从上面的绿色划分线以后均为字节阵列数据,用于绘制。而且每三个字节表示一个像素。

 

 

     描述完了上述的图的分块含义,现在就说一说BMP中的一些需要注意的方面,首先在位图字节阵列数据中BMP存储的图像数据是从左下角的像素开始,到最后的右上角像素。其中还有一个比较主要的概念,而且与绘图读取数据有关的概念是扫描行

 

    扫描行:扫描行指图像在存储器中一行像素的字节数据,图像扫描行的大小,取决于图象的颜色数目和用象素表示的图象宽度。
  BMP格式还有个非常重要的规定:要求每一扫描行的字节数据必须能被4整除,也就是dword对齐(dword是一种数据类型,长度为4个字节)。如果图像的一行字节数不能被4整除,就需要在每行的末尾补齐0以达到规定。

 

    因此在我们的读取数据中需要根据BMP图像的宽度来判断是否被补0,判断方法就是先判断一行的字节数是否可以被4整除,如果整除则不需要补0,如果没有整除,则求出补的0的个数(具体计算方法是,bu_0_number =4 -  width(像素) * 3 % 4 ),那么就知道在每一行的末尾都补了bu_0_number0,因此我们在读取时绘制图片时就要忽略这些数据。(补充:求每一行的字节数 size = width * 3

 

    经过上面分析,我们已经可以着手写程序了,因为整个过程已经在我们脑袋中了。首先从上面可以看出,位图文件头部分的数据只有宽度和高度部分的数据对我们有作用(对于我们已经知道需要解析的图片是24位真彩BMP图片),下来有用的就是位图字节阵列部分的数据,里面每三个代表一个像素的RGB值(里面补0的部分忽略),字节存储的图片像素的顺序是从左下到右上,这样我们只需要读一组RGB值设置画笔颜色,然后绘制一个像素;读一组RGB值设置颜色再绘制一个像素就可以了......

 

     上面均是自己在解析过程中的思考过程,其实BMP也好其他什么文件格式的也好,对于我们来说,我们只在字节的角度去看它,我们需要知道的只是规则,如果没有,那我们就制定规则。

     自己也实现了一个附在下面,但是存在一个问题就是,当文件比较大时,读取速度很慢。。。。这就是需要考虑的。。。。

 下面附上一张解析的24位BMP图:

 

 

  • 大小: 73.6 KB
  • 大小: 554.5 KB
2
3
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics