依赖于设备的位图(DDB) ,CreateCompatibleBitmap用法
DDB(Device-dependent bitmap)依赖于具体设备,这主要体现在以下两个方面:
DDB的颜色模式必需与输出设备相一致。例如,如果当前的显示设备是256色模式,那么DDB必然也是256色的,即一个像素用一个字节表示。
在256色以下的位图中存储的像素值是系统调色板的索引,其颜色依赖于系统调色板。
由于DDB高度依赖输出设备,所以DDB只能存在于内存中,它要么在视频内存中,要么在系统内存中。
11.3.1 DDB的创建
MFC的CBitmap类封装了DDB。该类提供了几个函数用来创建DDB:
BOOL LoadBitmap( LPCTSTR lpszResourceName );
BOOL LoadBitmap( UINT nIDResource );
该函数从资源中载入一幅位图,若载入成功则返回TRUE。资源位图实际上是一个DIB,该函数在载入时把它转换成了DDB。
BOOL CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitcount, const void* lpBits );
该函数用来创建一幅空白的DDB。参数nWidth和nHeight以像素为单位说明了位图的宽度和高度。nPlanes是DDB的色平面数,nBitcount是每个色平面的颜色位数。一般来说,nPlanes为1,而nBitcount代表DDB中每个像素值所占的位数,但在创建16色DDB时,nPlanes为4,而nBitcount为1。参数lpBits指向存储像素阵列的数组,该数组应该逐行存储位图的每个像素值。注意,数组中每行像素的数目必需是偶数个字节,如果是奇数,则应该用0补足。若创建成功函数返回TRUE。
BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );
该函数创建一个与指定设备上下文兼容的DDB。参数pDC指向一个设备上下文,nWidth和nHeight是DDB的尺寸。若创建成功函数返回TRUE。
可以调用CBitmap的成员函数GetBitmap来查询DDB的各种属性(如尺寸):
int GetBitmap( BITMAP* pBitMap );
该函数用来获得与DDB有关的信息,参数pBitMap指向一个BITMAP结构。BITMAP结构的定义为:
typedef struct tagBITMAP {
LONG bmType; //必需为0
LONG bmWidth; //位图的宽度(以像素为单位)
LONG bmHeight; //位图的高度(以像素为单位)
LONG bmWidthBytes; //每一扫描行所需的字节数,应是偶数
WORD bmPlanes; //色平面数
WORD bmBitsPixel; //色平面的颜色位数
LPVOID bmBits; //指向存储像素阵列的数组
} BITMAP;
11.3.2 DDB的用途
DDB的主要用途是保存位图。要保存的位图可以来自资源位图,也可以是一个绘图的结果。
前面说过,在256色以下的显示模式中,DDB中的像素值是系统调色板的索引。一般在系统调色板中除了保留的20种静态颜色外,其它表项都有可能被应用程序改变。如果DDB中有一些像素值是指向20种静态颜色以外的颜色,那么该位图的颜色将是不稳定的。因此,DDB不能用来长期存储色彩丰富的位图。如果位图使用的大部分颜色都是20种保留色,则该位图可以用CBitmap对象保存在内存中。例如,用CDC::LoadBitmap载入的资源位图一般都是颜色较简单的位图,对于那些颜色比较丰富的位图,只有使用下面将要介绍的DIB才能长期保存。
在窗口中显示DDB的方法有些特别,其过程分以下几步:
构建一个CDC对象,然后调用CDC::CreateCompatibleDC创建一个兼容的内存设备上下文。
调用CDC::SelectObject将DDB选入内存设备上下文中。
调用CDC::BitBlt或CDC::StretchBlt将DDB从内存设备上下文中输出到窗口的设备上下文中。
调用CDC::SelectObject把原来的DDB选入到内存设备上下文中并使新DDB脱离出来。
下面这段代码在视图中显示了一个DDB:
void CMyView::OnDraw( CDC* pDC)
{
. . .
CDC MemDC;
CBitmap *oldBmp;
BITMAP bmpInfo;
int bmWidth,bmHeight;
MemDC.CreateCompatibleDC(pDC);
oldBmp=MemDC.SelectObject(&m_Bitmap); //m_Bitmap是一个CBitmap对象
m_Bitmap.GetBitmap(&bmpInfo); //获取位图的尺寸
bmWidth=bmpInfo.bmWidth;
bmHeight=bmpInfo.bmHeight;
pDC->BitBlt(0,0,bmWidth,bmHeight,&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(oldBmp); //使位图m_Bitmap脱离设备上下文
. . .
}
函数CDC::BitBlt的声明为:
BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );
该函数把源设备上下文中的位图复制到本身的设备上下文中,两个设备上下文可以是内存设备上下文,也可以是同一个设备上下文。参数x和y是目的矩形的逻辑坐标,参数nWidth和nHeight说明了目的矩形及源位图的宽和高。pSrcDC指向源设备上下文,xSrc和ySrc说明了源矩形相对于源位图左上角的偏移。参数dwRop指定了光栅操作(ROP)代码,一些常用的ROP代码如表11.2所示。
表11.2 常用的ROP代码
ROP码 |
含义 |
BLACKNESS |
输出黑色 |
DSTINVERT |
反转目的位图 |
MERGECOPY |
用与操作把图案(Pattern)与源位图融合起来 |
MERGEPAINT |
用或操作把反转的源位图与目的位图融合起来 |
NOTSRCCOPY |
把源位图反转然后拷贝到目的地 |
NOTSRCERASE |
用或操作融合源和目的位图,然后再反转 |
PATCOPY |
把图案拷贝到目的位图中 |
PATINVERT |
用异或操作把图案与目的位图相融合 |
PATPAINT |
用或操作融合图案和反转的源位图,然后用或操作把结果与目的位图融合 |
SRCAND |
用与操作融合源位图和目的位图 |
SRCCOPY |
把源位图拷贝到目的位图 |
SRCERASE |
先反转目的位图,再用与操作将其与源位图融合 |
SRCINVERT |
用异或操作融合源位图和目的位图 |
SRCPAINT |
用或操作融合源位图和目的位图 |
WHITENESS |
输出白色 |
函数CDC::StretchBlt的声明为:
BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );
该函数把位图从源矩形拷贝到目的矩形中,如果源和目的矩形尺寸不同,那么将缩放位图的功能以适应目的矩形的大小。函数的大部分参数与BitBlt的相同,但多了两个参数nSrcWidth和nSrcHeight用来指定源矩形的宽和高。
DDB的一个重要用途是用作设备上下文的显示表面。每一个设备上下文都包含有一个DDB,该位图实际上是在显示设备的缓冲区中(如视频内存),我们可以把它看做设备上下文的显示表面,设备上下文用GDI函数绘图实际上就是修改它所包含的DDB(显示表面)的过程。
普通的设备上下文都是在屏幕上绘图的,而使用内存设备上下文则可以在系统内存中绘制图形。内存设备上下文是一种特殊的设备上下文,它将系统内存用作显示表面。程序可以使用内存设备上下文预先在系统内存中绘制复杂的图形,然后再快速地将其复制到实际的设备上下文的显示表面上,而绘制图形的结果仍保存在内存设备上下文的DDB中。
提示:有人可能会想到用BitBlt函数把绘图结果从显示设备拷贝到内存设备上下文中,这种方法可以工作,但有时会出错。当源矩形被别的窗口遮住时,BitBlt会把别的窗口中的像素拷贝下来。 |
内存设备上下文缺省的DDB是一个1×1的单色位图,如此小的显示表面显然是没有用的,因此程序一般要为内存设备对象选择一个合适大小的彩色DDB。
下面这段代码创建了一个内存设备上下文,并在其包含的DDB中画了一个灰色实心矩形,然后再把DDB输出到屏幕上。
void CMyView::OnDraw(CDC* pDC)
{
. . .
CDC MemDC;
CBitmap bm,*oldBmp;
MemDC.CreateCompatibleDC(pDC); //创建一个兼容的内存设备上下文
bm.CreateCompatibleBitmap(pDC,100,50); //创建一个兼容的DDB
oldBmp=MemDC.SelectObject(&bm);
MemDC.SelectStockObject(BLACK_PEN);
MemDC.SelectStockObject(GRAY_BRUSH);
MemDC.Rectangle(0,0,50,50); //在DDB中画一个矩形
pDC->BitBlt(0,0,100,50,&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(oldBmp); //使位图bm对象脱离设备上下文
. . .
}
在上面的代码中,绘图的结果保存在位图bm中,一旦调用MemDC.SelectObject(oldBmp)使位图bm脱离设备上下文,该位图就可以被其它对象使用。
下面是别人的一段代码,我无法理解CreateCompatibleBitmap函数的意义。兼容位图到里是做什么的?不明白!
CPaintDC dc(this); // 用于绘制的设备上下文
CRect rcClient;
GetClientRect(&rcClient);
//构造内存DC,用于画图
CDC m_MemDC;
m_MemDC.CreateCompatibleDC(&dc);
CBitmap btScreen;
btScreen.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
m_MemDC.SelectObject(&btScreen);
btScreen.DeleteObject();
//这里画图
...
dc.BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &m_MemDC, 0, 0, SRCCOPY);
m_MemDC.DeleteDC();
/////////////////////////////////////////////
一)
在上面代码中,如果我将
btScreen.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
换成
btScreen.LoadBitmap(IDB_BITMAP1);
能达到同样的效果吗?
二)
btScreen.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
m_MemDC.SelectObject(&btScreen);
CreateCompatibleBitmap创建一幅兼容位图后将该容易位图选入DC中,这个兼容位图到里是个什么图片?我发现,将该语句屏蔽后,程序运行后显示有些地方是黑的。不知道为什么。
三)
我想知道,CreateCompatibleBitmap到里创建了一幅什么位图啊?这个函数里面根本就没有填入任何位图信息嘛,难道它创建的是一幅空位图吗?它有什么意思啊?平常都是用LoadBitmap来创建位图的,真不知道什么时候该用CreateCompatibleBitmap函数,对这个函数一点都不理解,希望有高手能详细指点一下,重分答谢!
网友回复:记不清楚了,大概是每个新建的内存兼容DC里选中的位图都是1*1的灰度图,不创建一个兼容位图选进去的话,现实意义上说这个DC不可用(往上面bitblt)
网友回复:兼容位图是位图的各种信息与设备相兼容,主要是颜色位数要相同。
新创建的位图所有像素值都是0,通常是黑色。
兼容位图主要用于与设备相互复制图象,最常见的就是“双缓冲”绘图方式。
网友回复:CreateCompatibleBitmap用法
创建一幅与设备有关位图,它与指定的设备场景兼容
内存设备场景即与彩色位图兼容,也与单色位图兼容。这个函数的作用是创建一幅与当前选入hdc中的场景兼容。对一个内存场景来说,默认的位图是单色的。倘若内存设备场景有一个DIBSection选入其中,这个函数就会返回DIBSection的一个句柄。如hdc是一幅设备位图,那么结果生成的位图就肯定兼容于设备(也就是说,彩色设备生成的肯定是彩色位图)
如果nWidth和nHeight为零,返回的位图就是一个1×1的单色位图
一旦位图不再需要,一定用DeleteObject函数释放它占用的内存及资源
网友回复:一:可以,但是要注意位图的大小。
二:内存DC默认的位图是1x1单色位图,必须选入屏幕兼容的位图(也可以是其它格式)才能绘制、显示对应格式的颜色;
三:CreateCompatibleBitmap创建的位图是空的,一般初始化为黑色(和操作系统有关),关键是复制了参数中dc的位图格式。
依赖于设备的位图(DDB) ,CreateCompatibleBitmap用法的更多相关文章
- Device-Dependent Bitmaps (DDB) 设备相关位图
设备相关的位图(DDB)使用单一结构BITMAP结构描述.该结构的成员指定矩形区域的宽度和高度,以像素为单位;将条目从设备调色板映射到像素的数组的宽度;以及器件的颜色格式,在每个像素的颜色平面和位数方 ...
- 第15章 设备无关位图_15.3 DIB和DDB的结合
第15章 设备相关位图_15.3 DIB和DDB的结合 15.3.1 从DIB创建DDB (1)hBitmap =CreateDIBitmap(…)——注意这名称会误导,实际上创建的是DDB 参数 说 ...
- windows设备相关位图与设备无关位图
windows支持两种位图格式,DDB(device-dependent bitmap),DIB(device-independent bitmap).设备相关位图用于windows显示系统中,其图像 ...
- device-independent bitmap (DIB) 设备无关位图
设备无关位图即独立于设备的位图(DIB)与"Device-Dependent Bitmaps (DDB) 设备相关位图"相比,它不再依赖于具体的设备,从而更适合在不同的计算机之间传 ...
- 屏幕抓取程序 (位图DDB的例子)
屏幕抓取程序的意思是将整个屏幕图显示在应用程序的用户区中,等价于截图.对桌面窗口的操作:首先得知道桌面窗口的宽和高,获取宽和高需要利用窗口的设备句柄,而获取设备句柄需要知道窗口句柄,这一系列的连串关系 ...
- 第15章 设备无关位图_15.2 显示和打印DIB
15.2.1 探究DIB (1)DIB文件的结构 整个文件 紧凑DIB(整个文件除文件头) 文件头(File Header) 信息头(Information Header) 信息头(Informati ...
- 第15章 设备无关位图_15.1 DIB文件格式
15.1 DIB文件格式(一种文件格式,扩展名为BMP) 15.1.1 OS/2风格的DIB 文件格式 字段 说明 文件头 (BITMAPFILEHEADER) 1.共14个字节 2.缩写建议用bmf ...
- 位图和SVG用法比较
位图,亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的.这些点可以进行不同的排列和染色以构成图样.当放大位图时,可以看见赖以构成整个图像的无数单个方块.扩大位图尺寸的效果是增大单个像素 ...
- [2011-3-9 12:59 ]As3.0中的位图(Bitmap/BitmapData)用法
1.位图使用(模糊)滤镜 //创建一个矩形区域的BitmapData var bmd:BitmapData = new BitmapData(80, 30, false, 0xefefef); //画 ...
随机推荐
- jQuery validate api(转)
官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuery plugin: Validation 使用说明 转载 ...
- ADO.NET知识的运用一(Day 26)
哈哈,又到了总结的时间了,来回顾一下今天主要学了关于ADO.NET的哪些知识吧.(这次学的ADO访问数据库主要以访问SQL数据库为主) 理论: 首先我们要知道为什么要学习ADO.NET? 因为我们之 ...
- iOS中运用正则表达式
iOS中运用正则表达式来匹配短信验证码,电话号码,邮箱等是比较常见的. 在iOS中运用正则表达式主要有三种方式: -:通过谓词下面是实例代码: - (BOOL)regularExpresionWith ...
- redis之入门操作
下载安装 $ wget http://download.redis.io/releases/redis-3.2.3.tar.gz $ tar xzf redis-3.2.3.tar.gz $ cd r ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- Jquery对select的操作(附日历天数变化代码)
转载请注明出处. 逃不开传统的四种操作:增.删.改.查. <四处搜刮了jquery对select操作的代码,汇集一下,方便以后查看.日历天数变化代码为原创.> [增]: $("# ...
- codeforces 613A. Peter and Snow Blower
题目链接 给一个多边形, 一个多边形外的定点, 求这个点距离多边形的最短距离和最长距离. 最长距离肯定是和某个顶点的连线, 而最短距离是和点的连线或是和某条边的连线. 对于一条边上的两个点a, b, ...
- sql语句分析
show profile是由Jeremy Cole捐献给MySQL社区版本的.默认的是关闭的,但是会话级别可以开启这个功能.开启它可以让MySQL收集在执行语句的时候所使用的资源.为了统计报表,把pr ...
- strlen源码剖析
学习高效编程的有效途径之一就是阅读高手写的源代码,CRT(C/C++ Runtime Library)作为底层的函数库,实现必然高效.恰好手中就有glibc和VC的CRT源代码,于是挑了一个相对简 ...
- Qt5位置相关函数异同详解(附源码)
Qt5中提供了丰富的位置和区域大小相关函数.下面讲一讲他们的区别. 主要函数: 1.x(),y(),pos():获取整个窗体左上角的坐标位置. 2.frameGeometry():获取整个窗体左上角的 ...