DIB(Device-Independent Bitmap) 设备无关位图

时间:2021-03-02 19:30:45

位图一共有两种类型,即:设备相关位图(DDB)和设备无关位图(DIB)。DDB位图在早期的Windows系统(Windows 3.0以前)中是很普遍的,事实上它也是唯一的。然而,随着显示器制造技术的进步,以及显示设备的多样化,DDB位图的一些固有的问题开始浮现出来了,象BitBlt()这种函数就是基于DDB位图的。比如,它不能够存储(或者说获取)创建这张图片的原始设备的分辩率,这样,应用程序就不能快速的判断客户机的显示设备是否适合显示这张图片。为了解决这一难题,微软创建了DIB位图格式。
 
BMP文件是Windows保存图像的一种通用文件格式,在数字图像处理方面占有重要的地位。BMP文件中保存的图像数据是一种DIB(Device-Independent Bitmap,即设备无关位图),DIB是标准的Windows位图格式,它自带颜色信息,因此调色板管理非常容易。
 
BMP文件的结构
 
DIB位图包含下列的颜色和尺寸信息:
*     原始设备(即创建图片的设备)的颜色格式。
*     原始设备的分辩率。
*     原始设备的调色板
*     一个位数组,由红、绿、蓝(RGB)三个值代表一个像素。
*     一个数组压缩标志,用于表明数据的压缩方案(如果需要的话)。
以上这些信息保存在BITMAPINFO结构中,该结构由BITMAPINFOHEADER结构和两个或更多个RGBQUAD结构所组成。BITMAPINFOHEADER结构所包含的成员表明了图像的尺寸、原始设备的颜色格式、以及数据压缩方案等信息。RGBQUAD结构标识了像素所用到的颜色数据。
 
位图文件的组成 结构名称 符号
位图文件头(bitmap-file header)BITMAPFILEHEADERbmfh
位图信息头(bitmap-information header)BITMAPINFOHEADERbmih
彩色表(color table)RGBQUADaColors[]
图象数据阵列字节BYTEaBitmapBits[]

 
位图文件形式化结构
 偏移量 域的名称 大小 内容
 
 
 
图象文件
头0000h文件标识2 bytes两字节的内容用来识别位图的类型:
‘BM’ : Windows 3.1x, 95, NT, …
‘BA’ :OS/2 Bitmap Array
‘CI’ :OS/2 Color Icon
‘CP’ :OS/2 Color Pointer
‘IC’ : OS/2 Icon
‘PT’ :OS/2 Pointer
注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行。
 0002hFile Size1 dword用字节表示的整个文件的大小
 0006hReserved1 dword保留,必须设置为0
 000AhBitmap Data Offset1 dword从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量
位图信息头000EhBitmap Header Size1 dword位图信息头(Bitmap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:
28h - Windows 3.1x, 95, NT, …
0Ch - OS/2 1.x
F0h - OS/2 2.x
注:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。
 0012hWidth1 dword位图的宽度,以象素为单位
 0016hHeight1 dword位图的高度,以象素为单位
 001AhPlanes1 word位图的位面数(注:该值将总是1)
 001ChBits Per Pixel1 word每个象素的位数
1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)
4 - 16 色位图
8 - 256 色位图
16 - 16bit 高彩色位图
24 - 24bit 真彩色位图
32 - 32bit 增强型真彩色位图
 001EhCompression1 dword压缩说明:
0 - 不压缩 (使用BI_RGB表示)
1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示)
2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示)
3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)
 0022hBitmap Data Size1 dword用字节数表示的位图数据的大小。该数必须是4的倍数
 0026hHResolution1 dword用象素/米表示的水平分辨率
 002AhVResolution1 dword用象素/米表示的垂直分辨率
 002EhColors1 dword位图使用的颜色数。如8-比特/象素表示为100h或者 256.
 0032hImportant Colors1 dword指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
调色板数据根据BMP版本的不同而不同PaletteN * 4 byte调色板规范。对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:
1字节用于蓝色分量
1字节用于绿色分量
1字节用于红色分量
1字节用于填充符(设置为0)

图象数据根据BMP版本及调色板尺寸的不同而不同Bitmap Dataxxx bytes该域的大小取决于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。

 
 
位图文件程序结构
BITMAPFILEHEADER
位图文件头
(只用于BMP文件)
bfType = “BM”(0x4D42)            
bfSize                    
bfReserved1               
bfReserved2               
bfOffBits                  
BITMAPINFOHEADER
位图信息头
biSize                   
biWidth                  
biHeight                 
biPlance                 
biBitCount               
biCompression            
biSizeImage              
biXPelsPerMeter          
biYPelsPerMeter          
biClrUsed                
biClrImportant            
Palette
调色板
单色DIB有2个表项       
16色DIB有16个表项或更少
256色DIB有256个表项或更少
真彩色DIB没有调色板      
DIB Pixels
DIB图像数据
象素按照每行每列的顺序排列  
每一行的字节数必须是4的整倍数
 
位图读写
 
写bitmap的一般过程:
1:申明BITMAPFILEHEADER,并清空该结构:
BITMAPFILEHEADER bfh;
memset( &bfh, 0, sizeof( bfh ) );
2:初始化该结构:
bfn.bfType = 'MB';          // Bitmap
    //说明该文件的大小,cbBuffer为位图数据的大小
bfn.bfSize = sizeof(bfn) + cbBuffer + sizeof(BITMAPINFOHEADER);
//说明位图文件数据在整个位图文件中的偏移,即数据是从哪儿开始的
bfn.bfOffBits = sizeof(BITMAPINFORHEADER) + sizeof(BITMAPFILEHEADER);
3:将bfn写入文件
4:申明BITMAPINFOHEADER,并清空该结构:
BITMAPINFOHEADER bih;
memset( &bih, 0, sizeof( bih ) );
5:初始化该结构:
bih.biSize = sizeof( bih );
bih.biWidth = biWidth;             //位图的宽度
bih.biHeight = biHeight;        //位图的高度
bih.biPlanes = biPlanes;        //位图的位面数
bih.biBitCount = biBitCount;           //位图的色深
6:将bih写入文件
7:最后写入数据就行了。
 
读位图:(伪代码)
If open Bitmap file
Read two bytes (type) and if different than 0x4D42 stop
Ignore eight bytes
Read four bytes (start of image data)
Ignore four bytes
Read four bytes (width of bitmap)
Read four bytes (height of bitmap)
Ignore two bytes
Read two bytes (bit count of bitmap) and if different than 24 stop
Read four bytes (compression of bitmap) and if different than BI_RGB stop
Move to start of image data
Allocate memory for image data (3(one byte for red, other for
green other for blue) * ImageWidth * ImageHeight)
Read (3 * ImageWidth * ImageHeight) bytes from file to buffer
Swap the red and blue components of buffer
If ImageHeight is negative
Flip the buffer lines
End if
Close file