📄 chap11_3.htm
字号:
<html>
<head>
<title>11.3 依赖于设备的位图(DDB)</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
</head>
<body link="#3973DE" alink="#3973DE">
<font SIZE="5"><b><div align="center"><center>
<table border="0" width="615" cellspacing="0" cellpadding="0">
<tr>
</b><td><div align="center"><center><table border="0" width="615" cellpadding="0" cellspacing="0" height="20">
<tr>
<td width="377" bgcolor="#15397D" height="20"></td>
<td width="238" bgcolor="#000000" height="20"><p align="right"></font><span style="text-decoration: none"><a href="../../index.htm"><font color="#FFFFFF">电脑报Visual
C++网络教程</font></a></span></td>
</tr>
</table>
</center></div><font FACE="Times New Roman" SIZE="3"><b><p ALIGN="CENTER"></b></font><font color="#3973DE" FACE="Times New Roman" size="4">11.3 </font><font color="#3973DE" size="4">依赖于设备的位图</font><font color="#3973DE" FACE="Times New Roman" size="4">(DDB)</font><font FACE="Times New Roman" size="4"></p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">DDB(Device-dependent
bitmap)</font><font SIZE="3">依赖于具体设备,这主要体现在以下两个方面:</p>
<ul>
<li><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">DDB</font>的颜色模式必需与输出设备相一致。例如,如果当前的显示设备是<font FACE="Times New Roman" SIZE="3">256</font>色模式,那么<font FACE="Times New Roman" SIZE="3">DDB</font>必然也是<font FACE="Times New Roman" SIZE="3">256</font>色的,即一个像素用一个字节表示。</p>
</li>
<li><p ALIGN="JUSTIFY">在<font FACE="Times New Roman" SIZE="3">256</font>色以下的位图中存储的像素值是系统调色板的索引,其颜色依赖于系统调色板。</font></p>
</li>
</ul>
<p><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">由于</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">高度依赖输出设备,所以</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">只能存在于内存中,它要么在视频内存中,要么在系统内存中。</font><b><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font></b><font color="#3973DE" FACE="Times New Roman" SIZE="3">11.3.1
DDB</font><font SIZE="3" color="#3973DE">的创建</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">MFC</font><font SIZE="3">的</font><font FACE="Times New Roman" SIZE="3">CBitmap</font><font SIZE="3">类封装了</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">。该类提供了几个函数用来创建</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">:</p>
<blockquote>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BOOL LoadBitmap( LPCTSTR
lpszResourceName );<br>
BOOL LoadBitmap( UINT nIDResource );<br>
</font><font SIZE="3">该函数从资源中载入一幅位图,若载入成功则返回</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">。资源位图实际上是一个</font><font FACE="Times New Roman" SIZE="3">DIB</font><font SIZE="3">,该函数在载入时把它转换成了</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">。</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BOOL CreateBitmap( int
nWidth, int nHeight, UINT nPlanes, UINT nBitcount, const void* lpBits );<br>
</font><font SIZE="3">该函数用来创建一幅空白的</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">。参数</font><font FACE="Times New Roman" SIZE="3">nWidth</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">nHeight</font><font SIZE="3">以像素为单位说明了位图的宽度和高度。</font><font FACE="Times New Roman" SIZE="3">nPlanes</font><font SIZE="3">是</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">的色平面数,</font><font FACE="Times New Roman" SIZE="3">nBitcount</font><font SIZE="3">是每个色平面的颜色位数。一般来说,</font><font FACE="Times New Roman" SIZE="3">nPlanes</font><font SIZE="3">为</font><font FACE="Times New Roman" SIZE="3">1</font><font SIZE="3">,而</font><font FACE="Times New Roman" SIZE="3">nBitcount</font><font SIZE="3">代表</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">中每个像素值所占的位数,但在创建</font><font FACE="Times New Roman" SIZE="3">16</font><font SIZE="3">色</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">时,</font><font FACE="Times New Roman" SIZE="3">nPlanes</font><font SIZE="3">为</font><font FACE="Times New Roman" SIZE="3">4,</font><font SIZE="3">而</font><font FACE="Times New Roman" SIZE="3">nBitcount</font><font SIZE="3">为</font><font FACE="Times New Roman" SIZE="3">1</font><font SIZE="3">。参数</font><font FACE="Times New Roman" SIZE="3">lpBits</font><font SIZE="3">指向存储像素阵列的数组,该数组应该逐行存储位图的每个像素值。注意,数组中每行像素的数目必需是偶数个字节,如果是奇数,则应该用</font><font FACE="Times New Roman" SIZE="3">0</font><font SIZE="3">补足。若创建成功函数返回</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">。</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BOOL
CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );<br>
</font><font SIZE="3">该函数创建一个与指定设备上下文兼容的</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">。参数</font><font FACE="Times New Roman" SIZE="3">pDC</font><font SIZE="3">指向一个设备上下文,</font><font FACE="Times New Roman" SIZE="3">nWidth</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">nHeight</font><font SIZE="3">是</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">的尺寸。若创建成功函数返回</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">。</font></p>
</blockquote>
</blockquote>
<p><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">可以调用</font><font FACE="Times New Roman" SIZE="3">CBitmap</font><font SIZE="3">的成员函数</font><font FACE="Times New Roman" SIZE="3">GetBitmap</font><font SIZE="3">来查询</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">的各种属性</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">如尺寸</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">:</p>
<blockquote>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">int GetBitmap( BITMAP*
pBitMap );<br>
</font><font SIZE="3">该函数用来获得与</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">有关的信息,参数</font><font FACE="Times New Roman" SIZE="3">pBitMap</font><font SIZE="3">指向一个</font><font FACE="Times New Roman" SIZE="3">BITMAP</font><font SIZE="3">结构。</font><font FACE="Times New Roman" SIZE="3">BITMAP</font><font SIZE="3">结构的定义为:</p>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">typedef struct tagBITMAP {
</p>
<p ALIGN="JUSTIFY">LONG bmType; //</font><font SIZE="3">必需为</font><font FACE="Times New Roman" SIZE="3">0</p>
<p ALIGN="JUSTIFY">LONG bmWidth; //</font><font SIZE="3">位图的宽度</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">以像素为单位</font><font FACE="Times New Roman" SIZE="3">)</p>
<p ALIGN="JUSTIFY">LONG bmHeight; //</font><font SIZE="3">位图的高度</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">以像素为单位</font><font FACE="Times New Roman" SIZE="3">)</p>
<p ALIGN="JUSTIFY">LONG bmWidthBytes; //</font><font SIZE="3">每一扫描行所需的字节数,应是偶数</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">WORD bmPlanes; //</font><font SIZE="3">色平面数</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">WORD bmBitsPixel; //</font><font SIZE="3">色平面的颜色位数</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">LPVOID bmBits; //</font><font SIZE="3">指向存储像素阵列的数组</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">} BITMAP;</p>
</blockquote>
</blockquote>
</blockquote>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font></b><font color="#3973DE" FACE="Times New Roman" SIZE="3">11.3.2
DDB</font><font SIZE="3" color="#3973DE">的用途</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">DDB</font><font SIZE="3">的主要用途是保存位图。要保存的位图可以来自资源位图,也可以是一个绘图的结果。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">前面说过,在</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">色以下的显示模式中,</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">中的像素值是系统调色板的索引。一般在系统调色板中除了保留的</font><font FACE="Times New Roman" SIZE="3">20</font><font SIZE="3">种静态颜色外,其它表项都有可能被应用程序改变。如果</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">中有一些像素值是指向</font><font FACE="Times New Roman" SIZE="3">20</font><font SIZE="3">种静态颜色以外的颜色,那么该位图的颜色将是不稳定的。因此,</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">不能用来长期存储色彩丰富的位图。如果位图使用的大部分颜色都是</font><font FACE="Times New Roman" SIZE="3">20</font><font SIZE="3">种保留色,则该位图可以用</font><font FACE="Times New Roman" SIZE="3">CBitmap</font><font SIZE="3">对象保存在内存中。例如,用</font><font FACE="Times New Roman" SIZE="3">CDC::LoadBitmap</font><font SIZE="3">载入的资源位图一般都是颜色较简单的位图,对于那些颜色比较丰富的位图,只有使用下面将要介绍的</font><font FACE="Times New Roman" SIZE="3">DIB</font><font SIZE="3">才能长期保存。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">在窗口中显示</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">的方法有些特别,其过程分以下几步:</p>
<blockquote>
<blockquote>
<p ALIGN="JUSTIFY">构建一个</font><font FACE="Times New Roman" SIZE="3">CDC</font><font SIZE="3">对象,然后调用</font><font FACE="Times New Roman" SIZE="3">CDC::CreateCompatibleDC</font><font SIZE="3">创建一个兼容的内存设备上下文。</p>
<p ALIGN="JUSTIFY">调用</font><font FACE="Times New Roman" SIZE="3">CDC::SelectObject</font><font SIZE="3">将</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">选入内存设备上下文中。</p>
<p ALIGN="JUSTIFY">调用</font><font FACE="Times New Roman" SIZE="3">CDC::BitBlt</font><font SIZE="3">或</font><font FACE="Times New Roman" SIZE="3">CDC::StretchBlt</font><font SIZE="3">将</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">从内存设备上下文中输出到窗口的设备上下文中。</p>
<p ALIGN="JUSTIFY">调用</font><font FACE="Times New Roman" SIZE="3">CDC::SelectObject</font><font SIZE="3">把原来的</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">选入到内存设备上下文中并使新</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">脱离出来。</font></p>
</blockquote>
</blockquote>
<p><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">下面这段代码在视图中显示了一个</font><font FACE="Times New Roman" SIZE="3">DDB</font><font SIZE="3">:</p>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">void CMyView::OnDraw( CDC*
pDC)</p>
<p ALIGN="JUSTIFY">{</p>
<p ALIGN="JUSTIFY"><b>. . .</p>
</b><p ALIGN="JUSTIFY">CDC MemDC;</p>
<p ALIGN="JUSTIFY">CBitmap *oldBmp;</p>
<p ALIGN="JUSTIFY">BITMAP bmpInfo;</p>
<p ALIGN="JUSTIFY">int bmWidth,bmHeight;</p>
<p ALIGN="JUSTIFY">MemDC.CreateCompatibleDC(pDC);</p>
<p ALIGN="JUSTIFY">oldBmp=MemDC.SelectObject(&m_Bitmap); //m_Bitmap</font><font SIZE="3">是一个</font><font FACE="Times New Roman" SIZE="3">CBitmap</font><font SIZE="3">对象</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">m_Bitmap.GetBitmap(&bmpInfo);
//</font><font SIZE="3">获取位图的尺寸</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">bmWidth=bmpInfo.bmWidth;</p>
<p ALIGN="JUSTIFY">bmHeight=bmpInfo.bmHeight;</p>
<p ALIGN="JUSTIFY">pDC->BitBlt(0,0,bmWidth,bmHeight,&MemDC,0,0,SRCCOPY);</p>
<p ALIGN="JUSTIFY">MemDC.SelectObject(oldBmp); //</font><font SIZE="3">使位图</font><font FACE="Times New Roman" SIZE="3">m_Bitmap</font><font SIZE="3">脱离设备上下文</p>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY"><b>. . .</p>
</b><p ALIGN="JUSTIFY">}</p>
</blockquote>
<p ALIGN="JUSTIFY"></font><font SIZE="3">函数</font><font FACE="Times New Roman" SIZE="3">CDC::BitBlt</font><font SIZE="3">的声明为:</p>
<blockquote>
<blockquote>
<blockquote>
</font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BOOL BitBlt( int x, int y,
int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );</font></p>
</blockquote>
</blockquote>
</blockquote>
<p><font SIZE="3"> </p>
<p ALIGN="JUSTIFY">该函数把源设备上下文中的位图复制到本身的设备上下文中,两个设备上下文可以是内存设备上下文,也可以是同一个设备上下文。参数</font><font FACE="Times New Roman" SIZE="3">x</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">y</font><font SIZE="3">是目的矩形的逻辑坐标,参数</font><font FACE="Times New Roman" SIZE="3">nWidth</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">nHeight</font><font SIZE="3">说明了目的矩形及源位图的宽和高。</font><font FACE="Times New Roman" SIZE="3">pSrcDC</font><font SIZE="3">指向源设备上下文,</font><font FACE="Times New Roman" SIZE="3">xSrc</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">ySrc</font><font SIZE="3">说明了源矩形相对于源位图左上角的偏移。参数</font><font FACE="Times New Roman" SIZE="3">dwRop</font><font SIZE="3">指定了光栅操作</font><font FACE="Times New Roman" SIZE="3">(ROP)</font><font SIZE="3">代码,一些常用的</font><font FACE="Times New Roman" SIZE="3">ROP</font><font SIZE="3">代码如表</font><font FACE="Times New Roman" SIZE="3">11.2</font><font SIZE="3">所示。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><b><font SIZE="3"> </p>
<p ALIGN="CENTER">表</font><font FACE="Times New Roman" SIZE="3">11.2 </font><font SIZE="3">常用的</font><font FACE="Times New Roman" SIZE="3">ROP</font><font SIZE="3">代码</font></b></p>
<table BORDER="1" CELLSPACING="1" CELLPADDING="1" WIDTH="579">
<tr>
<td WIDTH="22%"><b><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">ROP</font><font SIZE="3">码</font></b></td>
<td WIDTH="78%"><font SIZE="3"><b><p ALIGN="JUSTIFY">含义</b></font></td>
</tr>
<tr>
<td WIDTH="22%"><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">BLACKNESS</font></td>
<td WIDTH="78%"><font SIZE="3"><p ALIGN="JUSTIFY">输出黑色</font></td>
</tr>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -