BMP图像结构及其大小计算

转自http://hi.baidu.com/%D7%B7%D2%E4%B5%C4%C4%BE%CE%DD/blog/item/b34010eea7aa93e3b3fb95dc.html

 

       本文详细介绍了BMP图像结构,位图文件头、位图信息头及彩色表的数据结构及作用;深入阐述了BMP文件大小的精准计算方法,包括“补零”原则。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序,具体数据举例:

BMP文件开头:

424D 4690 0000 0000 0000 4600 0000*2800 0000 8000 0000 9000 0000 0100 1000 0300 0000 0090 0000 A00F 0000 A00F 0000 0000 0000 0000 0000*00F8 0000 E007 0000 1F00 0000 0000 0000*02F1 84F1 04F1 84F1 84F1 06F2 84F1 06F2 04F2 86F2 06F2 86F2 86F2 .... ....

BMP文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列,在上图中已用*分隔。注意:很多文章都分错了!!

 

一、位图文件头

typedef struct tagBITMAPFILEHEADER {
UINT bfType;       
// 
2字节1字节(1Byte=二进制8位(8bit=十六进制2
DWORD bfSize;     // 4字节
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;

11:(这里的数字代表的是"",即两个字节,下同)图像文件头。0x4D42="BM",表示是Windows支持的BMP格式。若问为什么加"BM"Windows就喜欢这么干。

22-3:整个文件大小。4690 0000,为00009046h=36934.

34:保留,必须设置为0

45:保留,必须设置为0。也可能考虑以后还能加点什么。

56-7:从文件开始到实际位图数据之间的字节偏移量。4600 0000,为00000046h=70(十进制),文件头14字节+下面的位图信息头40字节+此例彩色板16字节=70字节。

 

二、位图信息头

typedef struct tagBITMAPINFOHEADER {
DWORD biSize; 
LONG biWidth;     
//
4个字节
LONG biHeight; 
WORD biPlanes;    
//位图的位面数,该值总是被设为1
WORD biBitCount;  //
说明此位图的位数(bit数)
DWORD biCompression; 
DWORD biSizeImage; 
LONG biXPelsPerMeter; 
LONG biYPelsPerMeter; 
DWORD biClrUsed; 
DWORD biClrImportant;
} BITMAPINFOHEADER;

68-9:位图信息头所需字节数,固定值2800 0000=00000028h=40(十进制)。Windows开辟这4个字节有点浪费内存的说。

710-11:位图宽度,以像素为单位。8000 0000,为00000080h=128.

812-13:位图高度,以像素为单位。9000 0000,为00000090h=144.

914:位图的位面数,该值总是被设为1.  0100,为0001h=1.

1015:说明比特数/像素的颜色深度。有1(单色),42^4=16色),8256色),1665536色,又称64K色,高彩色),2416777216色,即16M色,真彩色),324294967296色,即4096M色,增强型真彩色)。1000,为0010h=16.由此可知,此例是16位位图,而不是真彩图(24位位图)。

1116-17:压缩说明:有0(不压缩),1RLE 88RLE压缩),2RLE 44RLE压缩,3Bitfields,位域存放)。RLE简单地说是采用像素数+像素值的方式进行压缩。T408采用的是位域存放方式,用两个字节表示一个像素,位域分配为r5b6g5。图中0300 000000000003h=3.

1218-19:说明图像的大小,以字节为单位。该数必须是4的倍数,数值上等于位图宽度×位图高度×每个像素字节数。0090 000000009000h=128×144×2=36864.

1320-21:用象素/米表示的水平分辨率。A00F 00000000 0FA0h=4000.

1422-23:用象素/米表示的垂直分辨率。A00F 00000000 0FA0h=4000.

1524-25:位图使用的彩色表中的颜色索引数。设为0的话,则说明使用所有调色板项。

1626-27:对图象显示有重要影响的颜色索引的数目。如果是0,表示都重要。

 

三、彩色表

对于调色板中的每个表项,用下述方法来描述RGB的值:

typedef struct tagRGBQUAD {
BYTE rgbBlue;    
 //1
字节用于蓝色分量
BYTE rgbGreen;    //1字节用于绿色分量
BYTE rgbRed;      //1字节用于红色分量
BYTE rgbReserved; // 1字节用于填充符(设置为0
} RGBQUAD;

注意:彩色表多在伪彩色(不够十进制16777216种颜色)时用到。对于24位(24bit)真彩色(2^24= 256蓝色*256绿色*256红色=16777216色)位图,又叫RGB彩色BMP图像,则不使用彩色板,因为位图中的RGB值就代表了每个象素的颜色。那要彩色表干嘛呢?在伪彩色图中,极端一点比如一幅512*512的伪彩色图就只有2种颜色,非黑(00000000)即红(FFFF0000),那么该图可以设为1位位图,彩色版中只有两色,每个像素其实1bit就可以表示,用半个字节(4bit)就足以表示了,何必每像素3个字节的浪费内存呢?

1728-35:彩色板为00F8 0000 E007 0000 1F00 0000 0000 0000,这幅伪彩色图中只有4种颜色,分别是:

00FB 0000FB00h=64256(十进制),某种混合色。

E007 000007E0h=2016(十进制),某种混合色。

1F00 0000001Fh=31(十进制),某种混合色。

0000 0000为纯黑色。

另外举几个颜色案例:


 

四、图像数据阵列

18) 36-...:每两个字节表示一个像素。阵列中的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素。

      

五、位图文件大小的精准计算方法

      8位(bit)位图:彩色版中有2^8=256种颜色,具体哪256种颜色可由调色板灵活规定,因此每个像素点最多有256种情况(颜色),故刚好可用两位十六进制码(16^2=256)表示,占1字节。一幅512×5128位位图大小计算方法:位图文件头(14字节)+位图信息头(40字节)+调色板(256×彩色表4字节)+实际像素点占内存512×512×1字节)=263 222字节(Byte)。

      24位位图:又名RGB真彩色图,含2^24=16 777 216=16M色,没有彩色表,原因上文已说明。每个像素点由3个字节(十六进制码6位)表示,每个字节负责控制一种颜色,分别为蓝(Blue)、绿(Green)、红(Red)。为什么每种颜色用1个字节控制呢?我们知道,图像中任何颜色都是由蓝、绿、红混合而成,而在24位位图中这三种颜色的跨度(深度)分别为256=2^8,占二进制8bit=1字节,故蓝、绿、红刚好可用1个字节表示。那么每个像素点可能的颜色就有256×256×256=2^24种。一幅256×25624位位图大小计算方法:位图文件头(14字节)+位图信息头(40字节)+实际像素点占内存256×256×3字节)=196 662字节(Byte)。

    需要注意的是,Windows有“补零”的习惯!即要求位图的每一行像素所占字节数必须被4整除。若不能倍4整除,则在该位图每一行的十六进制码末尾“补”1至3个字节的“00”。例如:一幅宽253×高25624位位图,微软在生成该图为实际文件时,计算每一行像素所占字节=253×3字节=759字节,检验其被4除余1,则在每行的十六进制码末尾加1个字节,补“00”,变为760字节。因此我们计算该图大小时应先判断是否“补零”,再得出算法:该图大小=位图文件头(14字节)+位图信息头(40字节)+实际像素点占内存高256×每行760字节)=194614字节(Byte)。

    有趣的是,“补零”只针对位图的宽进行检验,一幅宽256×高25324位位图,其大小=位图文件头(14字节)+位图信息头(40字节)+实际像素点占内存高253×每行768字节)=194358字节(Byte< 196 662字节(Byte)。这样,只是把此图像的宽和高颠倒,图像所占内存竟然变小了。


 

  • 13
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值