DIB(Device-Independent Bitmap,即设备无关位图)小知识

时间:2022-02-19 05:54:58

DIB(Device-Independent Bitmap,即设备无关位图)小知识

 

简介

 

位图一共有两种类型,即:设备相关位图(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)

BITMAPFILEHEADER

bmfh

位图信息头(bitmap-information header)

BITMAPINFOHEADER

bmih

彩色表(color table)

RGBQUAD

aColors[]

图象数据阵列字节

BYTE

aBitmapBits[]

 

位图文件形式化结构

 

偏移量

域的名称

大小

内容

 

 

 

图象文件

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”就行。

 

0002h

File Size

1 dword

用字节表示的整个文件的大小

 

0006h

Reserved

1 dword

保留,必须设置为0

 

000Ah

Bitmap Data Offset

1 dword

从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量

位图信息头

000Eh

Bitmap Header Size

1 dword

位图信息头(Bitmap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:

28h - Windows 3.1x, 95, NT, …

0Ch - OS/2 1.x

F0h - OS/2 2.x

注:在Windows95982000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。

 

0012h

Width

1 dword

位图的宽度,以象素为单位

 

0016h

Height

1 dword

位图的高度,以象素为单位

 

001Ah

Planes

1 word

位图的位面数(注:该值将总是1

 

001Ch

Bits Per Pixel

1 word

每个象素的位数

1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)

4 - 16 色位图

8 - 256 色位图

16 - 16bit 高彩色位图

24 - 24bit 真彩色位图

32 - 32bit 增强型真彩色位图

 

001Eh

Compression

1 dword

压缩说明:

0 - 不压缩 (使用BI_RGB表示)

1 - RLE 8-使用8RLE压缩方式(BI_RLE8表示)

2 - RLE 4-使用4RLE压缩方式(BI_RLE4表示)

3 - Bitfields-位域存放方式(BI_BITFIELDS表示)

 

0022h

Bitmap Data Size

1 dword

用字节数表示的位图数据的大小。该数必须是4的倍数

 

0026h

HResolution

1 dword

用象素/米表示的水平分辨率

 

002Ah

VResolution

1 dword

用象素/米表示的垂直分辨率

 

002Eh

Colors

1 dword

位图使用的颜色数。如8-比特/象素表示为100h或者 256.

 

0032h

Important Colors

1 dword

指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要

调色板数据

根据BMP版本的不同而不同

Palette

N * 4 byte

调色板规范。对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:

1字节用于蓝色分量

1字节用于绿色分量

1字节用于红色分量

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

图象数据

根据BMP版本及调色板尺寸的不同而不同

Bitmap Data

xxx bytes

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

位图文件程序结构

BITMAPFILEHEADER

位图文件头

(只用于BMP文件)

bfType = “BM”(0x4D42)            

bfSize                    

bfReserved1               

bfReserved2               

bfOffBits                  

BITMAPINFOHEADER

位图信息头

biSize                   

biWidth                  

biHeight                 

biPlance                 

biBitCount               

biCompression            

biSizeImage              

biXPelsPerMeter          

biYPelsPerMeter           

biClrUsed                

biClrImportant            

Palette

调色板

单色DIB2个表项       

16DIB16个表项或更少

256DIB256个表项或更少

真彩色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