您的位置:首页 > 其它

关于“设备无关位图”!

2011-11-03 17:14 399 查看
BMP图像文件是Windows
3.X 所采用的图像文件格式,几乎所有Windows 上的应用软件都支持这种图像文件,其中最常见的就是Windows本身所附的绘图软件(Paint-Brush),所以欲在Windows上探讨图像的文件格式,势必要对BMP有一个完整而全面的认识。

BMP图像分为两类,DDB和DIB,DDB(device-dependent bitmap)即为设备相关位图,DIB(device-independent bitmap)即为设备无关位图。

DDB中不包括颜色信息,显示时是系统的调色板为基础进行各位的颜色映射的,Windows只能保证系统调色板的前20种颜色稳定不变,所以DDB只能保证正确显示色彩少于20色的位图,这便是局限性。所以现在研究的基本上都是基于DIB的图像文件。

DIB(设备无关位图)可以在不同的机器或系统中显示位图所固有的颜色。与DDB相比而言,DIB是一种外部的位图格式,经常存储以BMP为后缀的位图文件。DIB位图还支持图像数据的压缩。BMP文件由文件头、位图信息头、颜色信息和图像数据四部分组成。位图结构如图3-1所示:

位图文件头结构BITMAPFILEHEADER

位图信息头结构BITMAPINFOHEADER

位图调色板RGBQUAD

位图像素数据

图3-1 DIB位图结构

1. BMP文件头:

BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。其结构定义如下:

typedef struct tagBITMAPFILEHEADER

{

WORD bfType;

WORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

WORD bfOffBits;

}BITMAPFILEHEADER,FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;

该结构的长度是固定的,为14个字节,各个域的说明如下:

 bfType:指定文件类型,必须是0x4d42,即字符串“BM”。

 bfSize:指定文件大小,包括这14个字节。

 bfReserved1,bfReserved2:保留字,为0。

 bfOffBits:从文件头到实际的位图数据的偏移字节数,即图1中前三个部分的长度之和。

2. 位图信息头:

BMP位图信息头数据用于说明位图的尺寸等信息。

typedef struct tagBITMAPINFOHEADER

{

DWORD biSize;

LONG biWidth;

LONG biHeight;

WORD biPlanes;

WORD biBitCount;

DWORD biCompression;

DWORD biSizeImage;

LONG biXPelsPerMeter;

LONG biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

}BITMAPINFOHEADER,FAR*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;

该结构的长度也是固定的,为40个字节,各个域的说明如下:

 biSize:指定这个结构的长度,为40个字节。

 biWidth:指定图像的宽度,单位是象素。

 biHeight:指定图像的高度,单位是象素。

 biPlanes:必须是1。

 biBitCount:指定表示颜色时用到的位数,常用的值为1(黑白二色图)、4(16色图)、8(256色图)、24(真彩色图)。

 biCompression:指定位图是否压缩,有效值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。Windows位图可采用RLE4和RLE8的压缩格式,BI_RGB表示不压缩。

 biSizeImage:指定实际的位图数据占用的字节数,可用以下的公式计算出来:

biSizeImage = biWidth’× biHeight

要注意的是:上述公式中的biWidth’必须是4的整数倍(不是biWidth,而是大于或等于biWidth的离4最近的整数倍)。如果biCompression为BI_RGB,则该项可能为0。

 biXPelsPerMeter:指定目标设备的水平分辨率。

 biYPelsPerMeter:指定目标设备的垂直分辨率。

 biClrUsed:指定本图像实际用到的颜色数,如果该值为0,则用到的颜色数为2的biBitCount次幂。

 biClrImportant:指定本图像中重要的颜色数,如果该值为0,则认为所有的颜色数都是重要的。

3. 图调色板(RGBQUAD):

第三部分为调色板。有些位图需要调色板,有些位图,如真彩色图,不需要调色板,它们的BITMAPINFOHEADER后面直接是位图数据。

调色板实际上是一个数组,共有biClrUsed个元素(如果该值为0,则有2的biBitCount次幂个元素)。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其数据结构定义如下:

typedef struct tagRGBQUAD

{

BYTE rgbBlue;

BYTE rgbGreen;

BYTE rgbRed;

BYTE rgbReserved;

}RGBQUAD;

其中:

 rgbBlue:该颜色的蓝色分量。

 rgbGreen:该颜色的绿色分量。

 rgbRed:该颜色的红色分量。

 rgbReserved:保留值。

4. 图像数据:

对于用到调色板的位图,图像数据就是该象素颜色在调色板中的索引值,对于真彩色图,图像数据就是实际的R、G、B值。

 对于2色图,用1位就可以表示该象素的颜色,所以1个字节可以表示8个象素。

 对于16色图,用4位可以表示一个象素的颜色,所以1个字节可以表示2个象素。

 对于256色图,1个字节刚好可以表示1个象素。

 对于真彩色图,3个字节才能表示1个象素。

BMP图像数据的存储顺序是由下往上、由左向右(即图像上下颠倒存储),而图像的宽度(以字节为单位)必须是4的倍数,倘若不到4的倍数则必须补足,并且图像的数据及其调色板数据存储格式为BGRBGR…而不是一般习惯的RGBRGB…。

1.Dib类的头文件定义

在所实现的CDib类中,将完成与DIB操作有关的大部分功能,例如把DDB转换成DIB、从BMP文件建立DIB、建立空白DIB、拷贝调色板、读取BMP文件、存储BMP文件、绘制图像等等。在自定义的类的头文件中所需加入的函数与变量具体如下:

class CDib:public CObject

{

public:

CDib(CBitmap& ddb,CPalette *palette);

CDib(char *bmpfile);

CDib(CFile& file);

CDib(int Width,int Height,int BitsPerPixel);

~CDib( );

//取得DIB相关信息

//返回像素阵列

void* GetBits( );

//返回每像素的位数

int GetBitsPerPixel( );

//返回图像尺寸

BOOL GetDimension(CSize& size);

DWORD Width( );

DWORD Height( );

//调色板大小

int GetPaletteCount( );

//每条扫描线所需的字节数

DWORD BytesPerLine( );

//取得调色板

CPalette* GetPalette( );

//绘图函数

//在DC上缩放输出

int StretchToDC(CDC& dc,CRect& src,CRect& dst,DWORD rop=SRCCOPY);

//在DC上等尺寸输出

int SetToDC(CDC& dc,CRect& src,CPoint& dst);

//输出到DDB

BOOL CopyToDDB(CBitmap& ddb);

//文件相关

//存文件

BOOL DoSaveFile(char* bmpfile);

//写入指定文件

BOOL DoWriteFile(CFile& file);

//读入指定文件

BOOL DoReadFile(CFile& file);

Protected:

//计算像素阵列的大小

long GetImageBodySize( );

//计算BITMAPINFOHEADER和RGBQUAD数组的大小

int GetBITMAPINFOSize( );

//初始化文件头的信息

void InitDibInfo(int BitsPerPixel,int w=0,int h=0);

//复制调色板

void CopyPalette(CPalette& palette);

//文件头

BITMAPINFO *DibInfo;

//像素阵列

void* DibBits;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: