BMP位图文件结构解析

来源:互联网 发布:淘宝打单 编辑:程序博客网 时间:2024/05/19 12:16

一、

http://hi.baidu.com/lewvan/blog/item/f6591b4c4f17c2fad72afcd8.html

 

 下面引自上述网址:

=========================================

该文章于2007年12月21日修改。

我所要介绍的是24位真彩色位图文件的结构。

一个24位真彩色位图文件包括以下个部分:位图文件头、位图信息头和颜色数据域,这都是我自己起的名字,不知是否与经典有出入,大家应该能够意会。

首先说说位图文件头。就目前来看我所见到过的位图文件头都位于位图文件的最前部,长都是14个字节,例如有这样一个位图文件(用16位编辑器打开浏览时的效果):

0           1             2             3           4           5           6           7           8           9            A          B           C          D           E          F

42          4D          86          00         00         00         00         00         00         00         36         00         00         00      28         00
00          00           05          00         00         00         05         00         00         00         01         00         18         00         00         00
00          00           50          00         00         00         C4        0E         00          00        C4         0E         00         00         00         00
00          00           00          00         00         00
         FF        00         00          FF        00         00         FF         00         00         FF
00          00           FF         00          00         00         00        FF         00         00         FF         00         00         FF         00        00
FF          00          00          FF         00         00         00         00         FF         00         00         FF         00         00         FF        00
00          FF          00          00          FF        00         FF        FF         FF          FF        FF         FF        FF         FF        FF        FF
FF          FF          FF         FF          FF        00         00         00         00         00         00          00         00         00         00         00
00           00          00          00          00         00

那么在第0行从左向右的前14个字节(红色部分)属于位图文件头,各个字节的意义是这样的:

42       4D:看作ASCII码,对应的字母为‘BM’,即表示该文件是位图文件;

86      00      00       00:四个字节用于表示改为图文件的大小尺寸,要注意的是它们是按低位到高位排列的,那么可以看出整个位图文件的尺寸是0x00000086字节,即134字节。不难得知,这四个字节最大可以表示4,294,967,296,即可以表示4GB的位图大小;

00      00      00      00:查资料知道,这4个字节是保留位,用于存储文件大小的数据。而我没有找到超过4G的位图,因此不知道这四个自己究竟如何使用。不过可以推测可能是用跟前面4字节共64 bit来表示文件的大小。FAT32文件系统下不支持超过4GB的文件,NTFS系统支持;

36      00      00      00:也是按从低位到高位排列的,用于表示改位图颜色数据域相对文件开始处的偏移量,可以看到这个位图的颜色数据域是从0x00000036字节处开始的(这里有点想不通,既然前面要用8个字节表示文件大小,为什么这里的偏移量只有4字节?)。

以上就是位图文件头的情况,接下来是位图信息头,仍旧观察前面的位图,从第一行E序字节的28开始(蓝色部分)共40字节,各个字节的含义是:

28 00 00 00:表示信息头的长度,0x00000028=40,即位图信息头占40个字节;

05      00 00 00:表示位图宽度,单位为像素。即位图的宽度为5个像素;

05      00      00 00:表示位图高度,单位为像素。即位图的高度为5个像素;

01 00:表示位图设备级别;

18 00:位图级别,0x0018=24,即24位真彩色;

00 00 00 00:表示压缩类型,为零表示不压缩;

50 00 00 00:用于表示颜色数据区的实际长度,16进制,单位为字节,这里是80字节;

00 00 00 00:表示水平分辨率,具体什么意思还不清楚;

00 00 00 00:表示垂直分辨率;

C4 0E 00 00:表示位图实际使用的颜色表中的颜色变址数。

C4 0E 00 00:表示位图显示过程中被认为重要颜色变址数。

最后是颜色数据域。有一点要说明,颜色数据区中每一行的数据长度必须是4的整数倍,为了做到这一点,颜色数据区每一行都可能需要进行补齐。例如上述图片宽5像素,高5像素,而每个像素占3个字节,这样似乎颜色数据区应该为5*5*3=75字节,但是文件信息头中记录的却是80字节,实际上多出的5个字节被分到了每一行用于补齐。还有一个尝试要提醒大家:位图颜色数据域是从位图的最后一行的最左端开始记录颜色信息的,而不是通常认为的位图第一行最左端。此外,色光三原色的记录顺序在文件中是蓝、绿、红。总的来说,观察上面的文件情况,可以看出文件的第一行为黑色,行末补了一个全零字节,第二行为白色,第三行为红色,第四行为绿色,第五行为蓝色,每一行的末尾都用一个全零字节补齐(不知道是否一定要补全零字节,我尝试胡乱修改补齐字节之后并未发现影响图片显示的情况)。

之所以研究查找这方面的资料,是因为我打算做一个能把非图片文件转换为24为真彩色DIB图片的小软件,这样就可以把诸如.EXE、.RAR、.TXT之类的文件上传到百度空间里了,不过仍然需要有一个网络空间来存储供用户下载的转换器,不知道这个软件到底有没有用,也不知道我研究这一堆有没有用。不过还是做出来吧!能看到.EXE文件转换成为图片的样子也是很令人兴奋的。

 

=========================================

 

二、

《bmp图像文件格式》

http://blog.csdn.net/xuzhihong_gdut/archive/2007/08/18/1749223.aspx

 

=========================================

BMPbitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。在系统中以BMP为扩展名保存。
  打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图(当然,也可以用其它工具软件生成)。建议刚开始通过UtralEdit-32等二进制软件来查看bmp图像以增加对该文件格式的了解。

BMP文件头结构;

接下来是BMP信息头

现在讲解BMP4个组成部分:

1.文件头信息块(14个字节)

typedef struct tagBITMAPFILEHEADER

{

WORD bfType;                     文件类型,一定是‘BM’

DWORD bfSize;                文件大小,字节单位

WORD bfReserved1;            保留位

WORD bfReserved2;               保留位

DWORD bfOffBits;                    位图矩阵偏移量,是相对于文件开头的偏移量,字节单位

} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

0000-0001:文件标识,为字母ASCII“BM”
0002-0005
:文件大小。
0006-0009
:保留,每字节以“00”填写。
000A-000D
:记录图像数据区的起始位置。各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。

2.图像描述信息块(40个字节)

typedef struct tagBITMAPINFO

{

BITMAPINFOHEADER bmiHeader;

RGBQUAD bmiColors[1];

} BITMAPINFO, *PBITMAPINFO;

其中BITMAPINFOHEADER的结构体如下:

typedef struct tagBITMAPINFOHEADER

{

DWORD biSize;                     位图头大小,不一定有效的。

LONG biWidth;                      位图宽度,象素单位

LONG biHeight;             位图高度,象素单位

WORD biPlanes;                    平面数,一定为1

WORD biBitCount;          色彩深度,可以是14816,分别表示单色,16色,256色和真彩色

DWORD biCompression;        压缩方式0表示无压缩,1表示RLE压缩,2表示每个象素4比特的RLE压缩

DWORD biSizeImage;             图像区数据的大小

LONG biXPelsPerMeter;          水平分辨率,象素/

LONG biYPelsPerMeter;          垂直分辨率,象素/

DWORD biClrUsed;                 所实际使用的颜色表中的颜色数,不一定有效

DWORD biClrImportant;          重要的颜色数,不一定有效

} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

000E-0011:图像描述信息块的大小,常为28H
0012-0015
:图像宽度。
0016-0019
:图像高度。
001A-001B
:图像的plane总数(恒为1)。
001C-001D
:记录像素的位数,很重要的数值,图像的颜色数由该值决定。
001E-0021
:数据压缩方式(数值位0:不压缩;18位压缩;24位压缩)。
0022-0025
:图像区数据的大小。
0026-0029
:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。
002A-002D
:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。
002E-0031
:此图像所用的颜色数,如值为0,表示所有颜色一样重要。

3.颜色表

彩色表项的结构是
stypedef struct tagRGBQUAD

{

BYTE rgbBlue;

BYTE rgbGreen;

BYTE rgbRed;

BYTE rgbReserved;

} RGBQUAD;

  颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha32位位图的透明度值,一般不需要)。即首先4字节表示颜色号1的颜色,接下来表示颜色号2的颜色,依此类推。

4.图像数据区

  颜色表接下来位为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,即2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。所以,整个数据区的大小也会随之变化。究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8
  然而,未压缩的图像信息区的大小。除了真彩色模式外,其余的均大于或等于数据信息的大小。这是为什么呢?原因有两个:
  1.BMP文件记录一行图像是以字节为单位的。因此,就不存在一个字节中的数据位信息表示的点在不同的两行中。也就是说,设显示模式位16色,在每个字节分配两个点信息时,如果图像的宽度位奇数,那么最后一个像素点的信息将独占一个字节,这个字节的后4位将没有意义。接下来的一个字节将开始记录下一行的信息。
  2.为了显示的方便,除了真彩色外,其他的每行中颜色模式的行字节数要用数据“00”补齐为4的整数倍。如果显示模式为16色,当图像宽为19时,存储时每行则要补充4-(19/2+1)%4=2个字节(加1是因为里面有一个像素点要独占了一字节)。如果显示模式为256色,当图像宽为19时,每行也要补充4-19%4=1个字节。
  还有一点我要申明,当屏幕初始化为16256色模式时,一定要设置调色板或修正颜色值,否则无法得到正确的图像颜色。

=========================================

 

三、有了上述基础,

下述delphi 7 代码就可以理解了:

 

原创粉丝点击