bmp格式简介(图像文件头/位图信息头)DIB位图

头像
96 编辑
05-14 电脑

  BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。BMP位图文件默认的文件扩展名是BMP或者bmp。

  位图一共有两种类型,即:设备相关位图(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函数Get Device Caps(),并将第二个参数设为BITSPIXEL即可。

  显示设备的分辨率是以每米多少个像素来表明的,应用程序可以通过以下三个步骤来获取显示设备或打印机的水平分辨率:

  1. 调用Get Device Caps()函数,指定第二个参数为HORZRES。

  2. 再次调用Get Device Caps()函数,指定第二个参数为HORZSIZE。

  3. 用第一个返回值除以第二个返回值。即:Get Device Caps(hDC,HORZRES)/Get Device Caps(hDC,HORZSIZE);

  应用程序也可以使用相同的三个步骤来获取设备的垂直分辨率,不同之处只是要将HORZRES替换为VERTRES,把HORZSIZE替换为VERTSIZE,即可。

  调色板是被保存在一个RGBQUAD结构的数组中,该结构指出了每一种颜色的红、绿、蓝的分量值。位数组中的每一个索引都对应于一个调色板项(即一个RGBQUAD结构),应用程序将根据这种对应关系,将像素索引值转换为像素RGB值(真实的像素颜色)。应用程序也可以通过调用Get Device Caps()函数来获取当前显示设备的调色板尺寸(将该函数的第二个参数设为NUMCOLORS即可)。

  Win32 API支持位数据的压缩(只对8位和4位的底到上型DIB位图)。压缩方法是采用运行长度编码方案(RLE),RLE使用两个字节来描述一个句法,第一个字节表示重复像素的个数,第二个字节表示重复像素的索引值。有关压缩位图的详细信息请参见对BITMAPINFOHEADER结构的解释。

  应用程序可以从一个DDB位图创建出一个DIB位图,步骤是,先初始化一些必要的结构,然后再调用Get DIBits()函数。不过,有些显示设备有可能不支持这个函数,你可以通过调用Get Device Caps()函数来确定一下(Get Device Caps()函数在调用时指定RC_DI_BITMAP作为RASTERCAPS的标志)。

  应用程序可以用DIB去设置显示设备上的像素(译者注:也就是显示DIB),方法是调用Set DIBits To Device()函数或调用Stretch DIBits()函数。同样,有些显示设备也有可能不支持以上这两个函数,这时你可以指定RC_DIBTODEV作为RASTERCAPS标志,然后调用Get Device Caps()函数来判断该设备是否支持Set DIBits To Device()函数。也可以指定RC_STRETCHDIB作为RASTERCAPS标志来调用Get Device Caps()函数,来判断该设备是否支持Stretch DIBits()函数。

  如果应用程序只是要简单的显示一个已经存在的DIB位图,那么它只要调用Set DIBits To Device()函数就可以。比如一个电子表格软件,它可以打开一个图表文件,在窗口中简单的调用Set DIBits To Device()函数,将图形显示在窗口中。但如果应用程序要重复的绘制位图的话,则应该使用Bit Blt()函数,因为Bit Blt()函数的执行速度要比Set DIBits To Device()函数快很多。

  设备相关位图 (Device-Dependent Bitmaps)

  设备相关位图(DDB)之所以现在还被系统支持,只是为了兼容旧的Windows 3.0软件,如果程序员现在要开发一个与位图有关的程序,则应该尽量使用或生成DIB格式的位图。

  DDB位图是被一个单个结构BITMAP所描述,这个结构的成员标明了该位图的宽度、高度、设备的颜色格式等信息。

  DDB位图也有两种类型,即:可废弃的(discardable)DDB和不可废弃的(nondiscardable)DDB。可废弃的DDB位图就是一种当系统内存缺乏,并且该位图也没有被选入设备描述表(DC)的时候,系统就会把该DDB位图从内存中清除(即废弃)。不可废弃的DDB则是无论系统内存多少都不会被系统清除的DDB。API函数Create Discardable Bitmap()函数可用于创建可废弃位图。而函数Create Bitmap()、Create Compatible Bitmap()、和Create Bitmap Indirect()可用于创建不可废弃的位图。

  应用程序可以通过一个DIB位图而创建一个DDB位图,只要先初始化一些必要的结构,然后再调用Create DIBitmap()函数就可以。如果在调用该函数时指定了CBM_INIT标志,那么这一次调用就等价于先调用Create Compatible Bitmap()创建当前设备格式的DDB位图,然后又调用SetDIBits()函数转换DIB格式到DDB格式。(可能有些设备并不支持Set DIBits()函数,你可以指定RC_DI_BITMAP作为RASTERCAPS的标志,然后调用Get Device Caps()函数来判断一下)。

  图像文件头

  1)1-2:(这里的数字代表的是字节,下同)图像文件头。0x4d42=’BM’,表示是Windows支持的BMP格式。(注意:查ascii表B 0x42,M0x4d,bfType 为两个字节,B为low字节,M为high字节所以bfType=0x4D42,而不是0x424D,但注意)

  2)3-6:整个文件大小。4690 0000,为00009046h=36934。

  3)7-8:保留,必须设置为0。

  4)9-10:保留,必须设置为0。

  5)11-14:从文件开始到位图数据之间的偏移量(14+40+4*(2^biBitCount))(在有颜色板的情况下)。4600 0000,为00000046h=70,上面的文件头就是35字=70字节。

  位图信息头

  6)15-18:位图图信息头长度。

  7) 19-22:位图宽度,以像素为单位。8000 0000,为00000080h=128。

  8)23-26:位图高度,以像素为单位。9000 0000,为00000090h=144。

  9)27-28:位图的位面数,该值总是1。0100,为0001h=1。

  10)29-30:每个像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。1000为0010h=16。

  11)31-34:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。RLE简单地说是采用像素数+像素值的方式进行压缩。T408采用的是位域存放方式,用两个字节表示一个像素,位域分配为r5b6g5。图中0300 0000为00000003h=3(这张图片不存在颜色板)。

  12)35-38:用字节数表示的位图数据的大小,该数必须是4的倍数,数值上等于:一行所占的字节数×位图高度。0090 0000为00009000h=80×90×2h=36864。假设位图是24位,宽为41,高为30,则数值= (biWidth*biBitCount+31)/32*4*biHeight,即=(41*24+31)/32*4*30=3720

  13)39-42:用象素/米表示的水平分辨率。A00F 0000为0000 0FA0h=4000。

  14)43-46:用象素/米表示的垂直分辨率。A00F 0000为0000 0FA0h=4000。

  15)47-50:位图使用的颜色索引数。设为0的话,则说明使用所有调色板项。

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

  彩色板

  17)(55+0)到(50-1+2^biBitCount):彩色板规范。对于调色板中的每个表项,用下述方法来描述RGB的值:

  1字节用于蓝色分量

  1字节用于绿色分量

  1字节用于红色分量

  1字节用于填充符(设置为0)

  对于24-位真彩色图像就不使用彩色板,因为位图中的RGB值就代表了每个象素的颜色。

  如,彩色板为00F8 0000 E007 0000 1F00 0000 0000 0000,其中:

  00F8为F800h = 1111 1000 0000 0000(二进制),是蓝色分量的掩码。

  E007 为 07E0h = 0000 0111 1110 0000(二进制),是绿色分量的掩码。

  1F00为001Fh = 0000 0000 0001 [1] 1111(二进制),是红色分量的掩码。

  0000 总设置为0。

  将掩码跟像素值进行“与”运算再进行移位操作就可以得到各色分量值。看看掩码,就可以明白事实上在每个像素值的两个字节16位中,按从高到低取5、6、5位分别就是r、g、b分量值。取出分量值后把r、g、b值分别乘以8、4、8就可以补齐第个分量为一个字节,再把这三个字节按rgb组合,放入存储器(同样要反序),就可以转换为24位标准BMP格式了。

  图像数据阵列

  18)55(无调色板)-bfSize:每两个字节表示一个像素。阵列中的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素。

  //----图像处理-----BMP为DIB类型,从底向上显示---------

  //阵列中的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素。

  //下面的代码可以完成第一个字节表示位图左上角的象素,而最后一个字节表示位图右下角的象素,即正常的显示状态,便于操作。

7
3
什么是云主机 如何识别真假云主机 收集office 2007密钥(30个)
热门文章
随便看看
随便看看