Windows DDB和DIB技术应用(1)--DDB和DIB介绍

DIB设备无关位图

概述

DIB设备无关位图文件,这是一种文件格式,是为了保证用某个应用程序创建的位图图形可以被其它应用程序装载或显示一样。 DIB的与设备无关性主要体现在以下两个方面:DIB的颜色模式与设备无关。例如,一个256色的DIB即可以在真彩色显示模式下使用,也可以在16色模式下使用。256色以下(包括256色)的DIB拥有自己的颜色表,像素的颜色独立于系统调色板。由于DIB不依赖于具体设备,因此可以用来永久性地保存图象。DIB一般是以*.BMP文件的形式保存在磁盘中的,有时也会保存在*.DIB文件中。运行在不同输出设备下的应用程序可以通过DIB来交换图象。

结构

Borland C++下的框架类库OWL不同,MFC未提供现成的类来封装DIB。尽管Microsoft列出了一些理由,但没有DIB类确实给MFC用户带来很多不便。用户要想使用DIB,首先应该了解DIB的结构。

在内存中,一个完整的DIB由两部分组成:一个BITMAPINFO结构和一个存储像素阵列的数组BITMAPINFO描述了位图的大小,颜色模式和调色板等各种属性,其定义为

typedef struct tagBITMAPINFO

BITMAPINFOHEADER bmiHeader;

RGBQUAD bmiColors[1]; //颜色表

BITMAPINFO;

RGBQUAD结构用来描述颜色,其定义为

typedef struct tagRGBQUAD

BYTE rgbBlue; //蓝色的强度

BYTE rgbGreen; //绿色的强度

BYTE rgbRed; //红色的强度

BYTE rgbReserved; //保留字节,为0

} RGBQUAD;

注意,RGBQUAD结构中的颜色顺序是BGR,而不是平常的RGB

BITMAPINFOHEADER结构包含了DIB的各种信息,其定义为

typedef struct tagBITMAPINFOHEADER{

DWORD biSize; //该结构的大小

LONG biWidth; //位图的宽度(以像素为单位)

LONG biHeight; //位图的高度(以像素为单位)

WORD biPlanes; //必须为1

WORD biBitCount //每个像素的位数(148162432)

DWORD biCompression; //压缩方式,一般为0BI_RGB (未压缩)

DWORD biSizeImage; //字节为单位的图象大小(仅用于压缩位图)

LONG biXPelsPerMeter; //以目标设备每米的像素数来说明位图的水平分辨率

LONG biYPelsPerMeter; //以目标设备每米的像素数来说明位图的垂直分辨率

DWORD biClrUsed; /*颜色表的颜色数,若为0位图使用由biBitCount指定的最大颜色数*/

DWORD biClrImportant; //重要颜色的数目,若该值为0则所有颜色都重要

} BITMAPINFOHEADER;

DDB不同,DIB字节数组是从图象的最下面一行开始的逐行向上存储的,也即等于把图象倒过来然后在逐行扫描。另外,字节数组中每个扫描行的字节数必需是4的倍数,如果不足要用0补齐

定义

DIB可以存储在*.BMP*.DIB文件中。DIB文件是以BITMAPFILEHEADER结构开头的 typedef struct tagBITMAPFILEHEADER {

WORD bfType; //文件类型,必须为"BM"

DWORD bfSize; //文件的大小

WORD bfReserved1; //0

WORD bfReserved2; //0

DWORD bfOffBits; //存储的像素阵列相对于文件头偏移量

} BITMAPFILEHEADER;

紧随该结构的是一个BITMAPINFOHEADER结构,然后是RGBQUAD结构组成的颜色表(如果有的话),文件最后存储的是DIB的像素阵列。

DIB的颜色信息储存在自己的颜色表中,程序一般要根据颜色表为DIB创建逻辑调色板。在输出一幅DIB之前,程序应该将其逻辑调色板选入到相关的设备上下文中并实现到系统调色板中,然后再调用相关的GDI函数(::SetDIBitsToDevice::StretchDIBits)输出DIB。在输出过程中,GDI函数会把DIB转换成DDB,这项工作主要包括以下两步:

DIB的颜色格式转换成与输出设备相同的颜色格式。例如,在真彩色的显示模式下要显示一个256色的DIB,则应该将其转换成24位的颜色格式。

DIB像素的逻辑颜色索引转换成系统调色板索引。

编写类

由于MFC未提供DIB类,用户在使用DIB时将面临繁重的Windows API编程任务。幸运的是,Visual C++提供了一个较高层次的API,简化了DIB的使用。这些API函数实际上是由MFCDibLook例程提供的,它们位于DibLook目录下的dibapi.cppmyfile.cppdibapi.h文件中,主要包括:

ReadDIBFile //DIB文件读入内存

SaveDIB //DIB保存到文件中

CreateDIBPalette //DIB中创建一个逻辑调色板

PaintDIB //显示DIB

DIBWidth //返回DIB的宽度

DIBHeight //返回DIB的高度

DIB区块

DIB区块

DIB能拥有几种色彩组织中的一种,DDB必须是单色的或是与真实输出设备相同的格式。DIB是一个档案或记忆体块;DDBGDI点阵图物件并由点阵图代号表示。DIB能被显示或转换为DDB并转换回DIB,但是这里包含了装置无关位元和设备相关位元之间的转换程序。

您将遇到一个函式,它打破了这些规则。该函式在32位元Windows版本中发表,称为CreateDIBSection,语法为:

hBitmap = CreateDIBSection (

hdc, // device context handle

pInfo, // pointer to DIB information

fClrUse, // color use flag

ppBits, // pointer to pointer variable

hSection, // file-mapping object handle

dwOffset) ; // offset to bits in file-mapping object

CreateDIBSectionWindows API中最重要的函式之一(至少在使用点阵图时),然而您会发现它很深奥并难以理解。

个缫

让我们从它的名称开始,我们知道DIB是什么,但「DIB section」到底是什么呢?当您第一次检查CreateDIBSection时,可能会寻找该函式与DIB区块工作的方式。这是正确的,CreateDIBSection所做的就是建立了DIB的一部分(点阵图图素位元的记忆体块)。

我们看一下传回值,它是GDI点阵图物件的代号,这个传回值可能是该函式呼叫最会拐人的部分。传回值似乎暗示著CreateDIBSection在功能上与CreateDIBitmap相同。事实上,它只是相似但完全不同。实际上,从CreateDIBSection传回的点阵图代号与我们在本章和上一章遇到的所有点阵图建立函式传回的点阵图代号在本质上不同。

一旦理解了CreateDIBSection的真实特性,您可能觉得奇怪为什么不把传回值定义得有所区别。您也可能得出结论:CreateDIBSection应该称之为CreateDIBitmap,并且如同我前面所指出的CreateDIBitmap应该称之为CreateDDBitmap

使用

首先让我们检查一下如何简化CreateDIBSection,并正确地使用它。首先,把最後两个参数hSectiondwOffset,分别设定为NULL0。第二,仅在fColorUse参数设定为DIB_ PAL_COLORS时,才使用hdc参数,如果fColorUseDIB_RGB_COLORS(或0),hdc将被忽略(这与CreateDIBitmap不同,hdc参数用於取得与DDB相容的设备的色彩格式)。

因此,CreateDIBSection最简单的形式仅需要第二和第四个参数。第二个参数是指向BITMAPINFO结构的指针,我们以前曾使用过。我希望指向第四个参数的指标定义的指标不会使您困惑,它实际上很简单。

假设要建立每图素24位元的384×256位元DIB24位元格式不需要色彩对照表,因此它是最简单的,所以我们可以为BITMAPINFO参数使用BITMAPINFOHEADER结构。

您需要定义三个变数:BITMAPINFOHEADER结构、BYTE指标和点阵图代号:

BITMAPINFOHEADER bmih ;

BYTE * pBits ;

HBITMAP hBitmap ;

初始化BITMAPINFOHEADER结构的栏位

bmih->biSize = sizeof (BITMAPINFOHEADER) ;

bmih->biWidth = 384 ;

bmih->biHeight = 256 ;

bmih->biPlanes = 1 ;

bmih->biBitCount = 24 ;

bmih->biCompression = BI_RGB ;

bmih->biSizeImage = 0 ;

bmih->biXPelsPerMeter = 0 ;

bmih->biYPelsPerMeter = 0 ;

bmih->biClrUsed = 0 ;

bmih->biClrImportant = 0 ;

在基本准备後,我们呼叫该函式:

hBitmap = CreateDIBSection (NULL, (BITMAPINFO *) &bmih, 0, &pBits, NULL, 0) ;

注意问题

我们为第二个参数赋予BITMAPINFOHEADER结构的位址。这是常见的,但一个BYIE指标pBits的位址,就不常见了。这样,第四个参数是函式需要的指向指标的指标。

这是函式呼叫所做的:CreateDIBSection检查BITMAPINFOHEADER结构并配置足够的记忆体块来载入DIB图素位元。(在这个例子里,记忆体块的大小为384×256×3位元组。)它在您提供的pBits参数中储存了指向此记忆体块的指标。函式传回点阵图代号,正如我说的,它与CreateDIBitmap和其他点阵图建立函式传回的代号不一样。

然而,我们还没有做完,点阵图图素是未初始化的。如果正在读取DIB档案,可以简单地把pBits参数传递ReadFile函式并读取它们。或者可以使用一些程式码「人工」设定。

http://baike.baidu.com/link?url=V6ple7eEA3ButGvjQQydU-TT8wuukSuMjp1KDpFZMqTJiOW67I_QdpziN157aIWT

DDB设备相关位图

Windows中有两种类型的位图:DDB位图(与设备相关位图)DIB位图(与设备无关位图).与设备相关位图(device-dependent bitmap)是一种内部位图格式,它由MFC6.0版本CBitmap类定义,有一个与之关联的Windows数据结构.

DDB中不包括颜色信息,显示时是以系统的调色板为基础进行各位的颜色映射.它显示的图像依计算机显示系统的设置不同而不同,因此一般不存储文件.

MFC6.0定义了Cbitmap类对DDB结构BITMAPDDB位图操作进行了封装.结构BITMAP定义了DDB位图的类型宽度高度颜色格式和像素位置,其在Windows中定义如下:

typedef struct tagBITMAP

{

int bmType; //位图类型,必须设置为0

int bmWidth; //位图宽度

int bmHeight; //位图高度

int bmWidthBytes; //位图中每一扫描行中的字节数

BYTE bmPlanes; //颜色层数

BYTE bmbitsPixel; //每一像素所占的位数

void FAR* bmbits; //存放像素值内存块的地址

}BITMAP;

数字图像处理,使用较多的DIB位图,即与设备无关位图,DDB位图使用较少

DDB

dimethyl-4,4-

dimethoxy-5,6,5,6-dimethylene dioxy biphenyl-2,2dicarboxylate

http://baike.baidu.com/link?url=RX_wfY6St0W5GEnUqOE2URLzM4gE1wGrxwC39RHI0Iw39JQNzuHy3aYsKSwY6bYO#5

参考:http://blog.csdn.net/yue7603835/article/details/7408597

你可能感兴趣的:(windows,api,图像处理,DDB,DIB)