BMP图像格式详解

BMP图像格式详解
BMP图像格式详解
BMP是⼀种与硬件设备⽆关的图像⽂件格式,使⽤⾮常⼴。它采⽤位映射存储格式,除了图像深度可选以外,不采⽤其他任何压缩,因此,BMP⽂件所占⽤的空间很⼤。BMP⽂件的图像深度可选lbit、4bit、8bit及24bit。BMP⽂件存储数据时,图像的扫描⽅式是按从左到右、从下到上的顺序。 由于BMP⽂件格式是Windows环境中交换与图有关的数据的⼀种标准,因此在Windows环境中运⾏的图形图像软件都⽀持BMP图像格式。
⽂件结构
  典型的BMP图像⽂件由四部分组成:
  1:头数据结构,它包含BMP图像⽂件的类型、显⽰内容等信息;
  2:位图信息数据结构,它包含有BMP图像的宽、⾼、压缩⽅法,以及定义颜⾊等信息;
  3:调⾊板,这个部分是可选的,有些位图需要调⾊板,有些位图,⽐如真彩⾊图(24位的BMP)就不需要调⾊板;
  4:位图数据,这部分的内容根据BMP位图使⽤的位数不同⽽不同,在24位图中直接使⽤RGB,⽽其他的⼩于24位的使⽤调⾊板中颜⾊索引值。
  位图的类型:
  位图⼀共有两种类型,即:设备相关位图(DDB)和设备⽆关位图(DIB)。DDB位图在早期的Windows系统(Windows 3.0以前)中是很普遍的,事实上它也是唯⼀的。然⽽,随着显⽰器制造技术的进步,以及显⽰设备的多样化,DDB位图的⼀些固有的问题开始浮现出来了。⽐如,它不能够存储(或者说获取)创建这张图⽚的原始设备的分辨率,这样,应⽤程序就不能快速的判断客户机的显⽰设备是否适合显⽰这张图⽚。为了解决这⼀难题,微软创建了DIB位图格式。
 设备⽆关位图 (Device-Independent Bitmap)
  DIB位图包含下列的颜⾊和尺⼨信息:
  * 原始设备(即创建图⽚的设备)的颜⾊格式。
热收缩管
  * 原始设备的分辨率。
  * 原始设备的调⾊板
  * ⼀个位数组,由红、绿、蓝(RGB)三个值代表⼀个像素
  * ⼀个数组压缩标志,⽤于表明数据的压缩⽅案(如果需要的话)。
  以上这些信息保存在BITMAPINFO结构中,该结构由BITMAPINFOHEADER结构和两个或更多个RGBQUAD结构所组成。BITMAPINFOHEADER结构所包含的成员表明了图像的尺⼨、原始设备的颜⾊格式、以及数据压缩⽅案等信息。RGBQUAD结构标识了像素所⽤到的颜⾊数据。
  DIB位图也有两种形式,即:底到上型DIB(bottom-up),和顶到下型DIB(top-down)。底到上型DIB的原点(origin)在图像的左下⾓,⽽顶到下型DIB的原点在图像的左上⾓。如果DIB的⾼度值(由BITMAPINFOHEADER结构中的biHeight成员标识)是⼀个正值,那么就表明这个DIB是⼀个底到上型DIB,如果⾼度值是⼀个负值,那么它就是⼀个顶到下型DIB。注意:顶到下型的DIB位图是不能被压缩的。
  位图的颜⾊格式是通过颜⾊⾯板值(planes)和颜⾊位值(bitcount)计算得来的,颜⾊⾯板值永远是1,⽽颜⾊位值则可以是1、4、8、16、24、32其中的⼀个。如果它是1,则表⽰位图是⼀张单⾊位图(译者注:通常是⿊⽩位图,只有⿊和⽩两种颜⾊,当然它也可以是任意两种指定的颜⾊),如果它是4,则表⽰这是⼀张VGA位图,如果它是8、16、24、或是32,则表⽰该位图是其他设备所产⽣的位图。如果应⽤程序想获取当前显⽰设备(或打印机)的颜⾊位值(或称位深度),可调⽤API函数G
etDeviceCaps(),并将第⼆个参数设为BITSPIXEL即可。
  显⽰设备的分辨率是以每⽶多少个像素来表明的,应⽤程序可以通过以下三个步骤来获取显⽰设备或打印机的⽔平分辨率:
  1. 调⽤GetDeviceCaps()函数,指定第⼆个参数为HORZRES。
清明上河图 2013  2. 再次调⽤GetDeviceCaps()函数,指定第⼆个参数为HORZSIZE。
  3. ⽤第⼀个返回值除以第⼆个返回值。即:GetDeviceCaps(hDC,HORZRES)/GetDeviceCaps(hDC,HORZSIZE);
  应⽤程序也可以使⽤相同的三个步骤来获取设备的垂直分辨率,不同之处只是要将HORZRES替换为VERTRES,把HORZSIZE替换为VERTSIZE,即可。
  调⾊板是被保存在⼀个RGBQUAD结构的数组中,该结构指出了每⼀种颜⾊的红、绿、蓝的分量值。位数组中的每⼀个索引都对应于⼀个调⾊板项(即⼀个RGBQUAD结构),应⽤程序将根据这种对应关系,将像素索引值转换为像素RGB值(真实的像素颜⾊)。应⽤程序也可以通过调⽤GetDeviceCaps()函数来获取当前显⽰设备的调⾊板尺⼨(将该函数的第⼆个参数设为NUMCOLORS即可)。
  Win32 API⽀持位数据的压缩(只对8位和4位的底到上型DIB位图)。压缩⽅法是采⽤运⾏长度编码⽅案(RLE),RLE使⽤两个字节来描述⼀个句法,第⼀个字节表⽰重复像素的个数,第⼆个字节表⽰重复像素的索引值。有关压缩位图的详细信息请参见对BITMAPINFOHEADER结构的解释。
  应⽤程序可以从⼀个DDB位图创建出⼀个DIB位图,步骤是,先初始化⼀些必要的结构,然后再调⽤GetDIBits()函数。不过,有些显⽰设备有可能不⽀持这个函数,你可以通过调⽤GetDeviceCaps()函数来确定⼀下(GetDeviceCaps()函数在调⽤时指定
RC_DI_BITMAP作为RASTERCAPS的标志)。
  应⽤程序可以⽤DIB去设置显⽰设备上的像素(译者注:也就是显⽰DIB),⽅法是调⽤SetDIBitsToDevice()函数或调⽤StretchDIBits()函数。同样,有些显⽰设备也有可能不⽀持以上这两个函数,这时你可以指定RC_DIBTODEV作为RASTERCAPS标志,然后调⽤GetDeviceCaps()函数来判断该设备是否⽀持SetDIBitsToDevice()函数。也可以指定RC_STRETCHDIB作为RASTERCAPS标志来调⽤GetDeviceCaps()函数,来判断该设备是否⽀持StretchDIBits()函数。
  如果应⽤程序只是要简单的显⽰⼀个已经存在的DIB位图,那么它只要调⽤SetDIBitsToDevice()函数就可以。⽐如⼀个电⼦表格软件,它可以打开⼀个图表⽂件,在窗⼝中简单的调⽤SetDIBitsToDevice()函数,将图形显⽰在窗⼝中。但如果应⽤程序要重复的绘制位图的话,则应该使
⽤BitBlt()函数,因为BitBlt()函数的执⾏速度要⽐SetDIBitsToDevice()函数快很多。
  设备相关位图 (Device-Dependent Bitmaps)
  设备相关位图(DDB)之所以现在还被系统⽀持,只是为了兼容旧的Windows 3.0软件,如果程序员现在要开发⼀个与位图有关的程序,则应该尽量使⽤或⽣成DIB格式的位图。
  DDB位图是被⼀个单个结构BITMAP所描述,这个结构的成员标明了该位图的宽度、⾼度、设备的颜⾊格式等信息。
  DDB位图也有两种类型,即:可废弃的(discardable)DDB和不可废弃的(nondiscardable)DDB。可废弃的DDB位图就是⼀种当系统内存缺乏,并且该位图也没有被选⼊设备描述表(DC)的时候,系统就会把该DDB位图从内存中清除(即废弃)。不可废弃的DDB则是⽆论系统内存多少都不会被系统清除的DDB。API函数CreateDiscardableBitmap()函数可⽤于创建可废弃位图。⽽函数CreateBitmap()、CreateCompatibleBitmap()、和CreateBitmapIndirect()可⽤于创建不可废弃的位图。
  应⽤程序可以通过⼀个DIB位图⽽创建⼀个DDB位图,只要先初始化⼀些必要的结构,然后再调⽤CreateDIBitmap()函数就可以。如果在调⽤该函数时指定了CBM_INIT标志,那么这⼀次调⽤就等价于
先调⽤CreateCompatibleBitmap()创建当前设备格式的DDB位图,然后⼜调⽤SetDIBits()函数转换DIB格式到DDB格式。(可能有些设备并不⽀持SetDIBits()函数,你可以指定RC_DI_BITMAP作为RASTERCAPS的标志,然后调⽤GetDeviceCaps()函数来判断⼀下)。
  对应的数据结构:
  1:BMP⽂件组成
  BMP⽂件由、位图信息头、颜⾊信息和图形数据四部分组成。
  2:BMP⽂件头(14字节)
  BMP⽂件头数据结构含有BMP⽂件的类型、⽂件⼤⼩和位图起始位置等信息。
  其结构定义如下:
  typedef struct tagBITMAPFILEHEADER
  {
  WORD bfType; // 位图⽂件的类型,必须为BM(0-1字节)
  DWORD bfSize; // 位图⽂件的⼤⼩,以字节为单位(2-5字节)
  WORD bfReserved1; // 位图⽂件保留字,必须为0(6-7字节)
爪形手  WORD bfReserved2; // 位图⽂件保留字,必须为0(8-9字节)
  DWORD bfOffBits; // 位图数据的起始位置,以相对于位图(10-13字节)
  // ⽂件头的偏移量表⽰,以字节为单位
  } BITMAPFILEHEADER;
  3:位图信息头(40字节)
  BMP位图信息头数据⽤于说明位图的尺⼨等信息。
  typedef struct tagBITMAPINFOHEADER{
  DWORD biSize; // 本结构所占⽤字节数(14-17字节)
  LONG biWidth; // 位图的宽度,以像素为单位(18-21字节)
  LONG biHeight; // 位图的⾼度,以像素为单位(22-25字节)
  WORD biPlanes; // ⽬标设备的级别,必须为1(26-27字节)
  WORD biBitCount;// 每个像素所需的位数,必须是1(双⾊),(28-29字节)
  // 4(16⾊),8(256⾊)或24(真彩⾊)之⼀
  DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),(30-33字节)
  // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之⼀
  DWORD biSizeImage; // 位图的⼤⼩,以字节为单位(34-37字节)
  LONG biXPelsPerMeter; // 位图⽔平分辨率,每⽶像素数(38-41字节)
  LONG biYPelsPerMeter; // 位图垂直分辨率,每⽶像素数(42-45字节)
  DWORD biClrUsed;// 位图实际使⽤的颜⾊表中的颜⾊数(46-49字节)
  DWORD biClrImportant;// 位图显⽰过程中重要的颜⾊数(50-53字节)
  } BITMAPINFOHEADER;
  4:颜⾊表
  颜⾊表⽤于说明位图中的颜⾊,它有若⼲个表项,每⼀个表项是⼀个RGBQUAD类型的结构,定义⼀种颜⾊。RGBQUAD结构的定义如下:
  typedef struct tagRGBQUAD {
巴黎公社原则  BYTE rgbBlue;// 蓝⾊的亮度(值范围为0-255)
  BYTE rgbGreen; // 绿⾊的亮度(值范围为0-255)
  BYTE rgbRed; // 红⾊的亮度(值范围为0-255)
  BYTE rgbReserved;// 保留,必须为0
  } RGBQUAD;
  颜⾊表中RGBQUAD结构数据的个数有biBitCount来确定:
  当biBitCount=1,4,8时,分别有2,16,256个表项;
  当biBitCount=24时,没有颜⾊表项。
设备完好标准
  位图信息头和颜⾊表组成位图信息,BITMAPINFO结构定义如下:
  typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader; // 位图信息头
  RGBQUAD bmiColors[1]; // 颜⾊表
  } BITMAPINFO;
  5:位图数据
  位图数据记录了位图的每⼀个像素值,记录顺序是在扫描⾏内是从左到右,扫描⾏之间是从下到上。位图的⼀个像素值所占的字节数:  当biBitCount=1时,8个像素占1个字节;
  当biBitCount=4时,2个像素占1个字节;
  当biBitCount=8时,1个像素占1个字节;
  当biBitCount=24时,1个像素占3个字节;
  Windows规定⼀个扫描⾏所占的字节数必须是
  4的倍数(即以long为单位),不⾜的以0填充,
  biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight;
  具体数据举例:
  如某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⽂件可分为四个部分:位图⽂件头、位图信息头、彩⾊板、图像数据阵列,在上图中已⽤*分隔。
  ⼀、图像⽂件头
  1)1:(这⾥的数字代表的是"字",即两个字节,下同)图像⽂件头。0x4D42=’BM’,表⽰是Windows⽀持的。
  2)2-3:整个⽂件⼤⼩。4690 0000,为00009046h=36934。
  3)4-5:保留,必须设置为0。
  4)6-7:从⽂件开始到位图数据之间的偏移量。4600 0000,为00000046h=70,上⾯的⽂件头就是35字=70字节。
  ⼆、位图信息头
  5)8-9:位图图信息头长度。
  6)10-11:位图宽度,以像素为单位。8000 0000,为0000080h=128。
  7)12-13:位图⾼度,以像素为单位。9000 0000,为00000090h=144。
纪检监察工作论文  8)14:位图的位⾯数,该值总是1。0100,为0001h=1。
  9)15:每个像素的位数。有1(单⾊),4(16⾊),8(256⾊),16(64K⾊,⾼彩⾊),24(1
6M⾊,真彩
⾊),32(4096M⾊,增强型真彩⾊)。1000为0010h=16。
  10)16-17:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。RLE简单地说是采⽤像素数+像素值的⽅式进⾏压缩。T408采⽤的是位域存放⽅式,⽤两个字节表⽰⼀个像素,位域分配为r5b6g5。图中0300 0000为00000003h=3。
  11)18-19:⽤字节数表⽰的位图数据的⼤⼩,该数必须是4的倍数,数值上等于(≥位图宽度的最⼩的4的倍数)×位图⾼度×每个像素位数。0090 0000为00009000h=80×90×2h=36864。
  12)20-21:⽤象素/⽶表⽰的⽔平分辨率。A00F 0000为0000 0FA0h=4000。
  13)22-23:⽤象素/⽶表⽰的垂直分辨率。A00F 0000为0000 0FA0h=4000。
  14)24-25:位图使⽤的颜⾊索引数。设为0的话,则说明使⽤所有调⾊板项。
  15)26-27:对图象显⽰有重要影响的颜⾊索引的数⽬。如果是0,表⽰都重要。
  三、彩⾊板
  16)28-....(不确定):彩⾊板规范。对于调⾊板中的每个表项,⽤下述⽅法来描述RGB的值:
  1字节⽤于蓝⾊分量
  1字节⽤于绿⾊分量
  1字节⽤于红⾊分量
  1字节⽤于填充符(设置为0)
  对于24-位真彩⾊图像就不使⽤彩⾊板,因为位图中的RGB值就代表了每个象素的颜⾊。
  如,彩⾊板为00F8 0000 E007 0000 1F00 0000 0000 0000,其中:
  00FB 0000为FB00h=1111100000000000(⼆进制),是蓝⾊分量的掩码。
  E007 0000为 07E0h=0000011111100000(⼆进制),是绿⾊分量的掩码。
  1F00 0000为001Fh=0000000000011111(⼆进制),是红⾊分量的掩码。
  0000 0000总设置为0。
  将掩码跟像素值进⾏“与”运算再进⾏移位操作就可以得到各⾊分量值。看看掩码,就可以明⽩事实上在每个像素值的两个字节16位中,按从⾼到低取5、6、5位分别就是r、g、b分量值。取出分量值后把r、g、b值分别乘以8、4、8就可以补齐第个分量为⼀个字节,再把这三个字节按rgb组合,放⼊存储器(同样要反序),就可以转换为24位标准BMP格式了。
  四、图像数据阵列
  17)27(⽆调⾊板)-...:每两个字节表⽰⼀个像素。阵列中的第⼀个字节表⽰位图左下⾓的象素,⽽最后⼀个字节表⽰位图右上⾓的象素。
  五、存储算法
  BMP⽂件通常是不压缩的,所以它们通常⽐同⼀幅图像的压缩图像⽂件格式要⼤很多。例如,⼀个800×600的24位⼏乎占据
1.4MB空间。因此它们通常不适合在因特⽹或者其它低速或者有容量限制的媒介上进⾏传输。 根据颜⾊深度的不同,图像上的⼀个像素可以⽤⼀个或者多个字节表⽰,它由n/8所确定(n是位深度,1字节包含8个数据位)。图⽚浏览器等基于字节的ASCII值计算像素的颜⾊,然后从调⾊板中读出相应的值。更为详细的信息请参阅下⾯关于位图⽂件的部分。 n位2n种颜⾊的位图近似字节数可以⽤下⾯的
公式计算: BMP⽂件⼤⼩约等于 54+4*2的n次⽅+(w*h*n)/8,其中⾼度和宽度都是像素数。 需要注意的是上⾯公式中的54是位图⽂件的⽂件头,是彩⾊调⾊板的⼤⼩。另外需要注意的是这是⼀个近似值,对于n位的位图图像来说,尽管可能有最多2n中颜⾊,⼀个特定的图像可能并不会使⽤这些所有的颜⾊。由于彩⾊调⾊板仅仅定义了图像所⽤的颜⾊,所以实际的彩⾊调⾊板将⼩于。 如果想知道这些值是如何得到的,请参考下⾯⽂件格式的部分。 由于存储算法本⾝决定的因素,根据⼏个图像参数的不同计算出的⼤⼩与实际的⽂件⼤⼩将会有⼀些细⼩的差别。

本文发布于:2024-09-22 01:31:11,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/576563.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:位图   设备   像素   结构   图像   数据   字节
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议