📄 20000727004.htm
字号:
<HTML>
<HEAD>
<TITLE>DrawDib函数组的使用</TITLE>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR>
</HEAD>
<BODY aLink=#FF0000 bgColor=#ffffff leftMargin=0 link=#187800 topMargin=0
vLink=#990099>
<div align="center">
<table width="744" border="0" cellspacing="0" cellpadding="0" height="76">
<tr>
<td>
<p align="center"><font size="3"><b><br>
DrawDib函数组的使用</b></font></p>
<p align="left"><font lang="ZH-CN">作者:罗隽</font></p>
<p align="left"> Microsoft<font lang="ZH-CN">的针对与设备无关位图(</font>DIB<font lang="ZH-CN">位图),在其</font>WIN32
SDK<font lang="ZH-CN">的</font>Multimedia<font lang="ZH-CN">中提供了一组绘制</font>DIB<font lang="ZH-CN">位图的高性能函数组──</font>DrawDib<font lang="ZH-CN">函数组。</font>DrawDib<font lang="ZH-CN">函数组是一组不依赖于图形设备接口(</font>GDI<font lang="ZH-CN">)函数,而直接操作显存的函数组。它们支持</font>8<font lang="ZH-CN">位、</font>16<font lang="ZH-CN">位、</font>24<font lang="ZH-CN">位和</font>32<font lang="ZH-CN">位图象深度的</font>DIB<font lang="ZH-CN">。总的来说,</font>DrawDib<font lang="ZH-CN">函数组类似于</font>StretchDIBits<font lang="ZH-CN">函数,它们都提供了将图象拉伸和抖动的功能,然而,</font>DrawDib<font lang="ZH-CN">函数组还支持图象的解压、数据流以及更多的显示适配器。在某些情况下,</font>DrawDib<font lang="ZH-CN">函数组还具有更大的优越性。但是,在某些场合下,</font>DrawDib<font lang="ZH-CN">函数组却不能取代</font>StretchDIBits<font lang="ZH-CN">函数。下面就</font>DrawDib<font lang="ZH-CN">函数组和</font>StretchDIBits<font lang="ZH-CN">函数使用的场合加以区别和说明:
</font>
<div align="left">
<ul>
<li> <font lang="ZH-CN">颜色信息表格式。</font>DrawDib<font lang="ZH-CN">函数组只支持颜色信息表格式为</font>DIB_RGB_COLORS<font lang="ZH-CN">格式的图象,如果要显示以</font>DIB_PAL_COLORS<font lang="ZH-CN">或</font>DIB_PAL_INDICES<font lang="ZH-CN">格式的图象,则必须用</font>StretchDIBits<font lang="ZH-CN">函数。</font></li>
<li> <font lang="ZH-CN">光栅操作模式。</font>DrawDib<font lang="ZH-CN">函数组只能使用</font>SRCCOPY<font lang="ZH-CN">光栅操作模式,如果要求不仅仅使用</font>SRCCOPY<font lang="ZH-CN">模式的话,只能用</font>StretchDIBits<font lang="ZH-CN">函数。同样地,如果要使用其他光栅操作,例如</font>XOR<font lang="ZH-CN">,只能用</font>StretchDIBits<font lang="ZH-CN">函数。</font></li>
<li> <font lang="ZH-CN">视频及动画回放的质量。</font>DrawDib<font lang="ZH-CN">函数组支持数据流应用,诸如视频片和动画序列,它比</font>StretchDIBits<font lang="ZH-CN">函数提供了更高的图象质量以及对回放过程的改进。</font></li>
<li> <font lang="ZH-CN">显示适配器。</font>DrawDib<font lang="ZH-CN">函数组比</font>StretchDIBits<font lang="ZH-CN">函数支持更多的显示适配器。</font>DrawDib<font lang="ZH-CN">函数组支持使用</font>4<font lang="ZH-CN">位图象深度提供</font>16<font lang="ZH-CN">色调色板的</font>VGA<font lang="ZH-CN">适配器,使用</font>8<font lang="ZH-CN">位图象深度提供</font>256<font lang="ZH-CN">色调色板的</font>SVGA<font lang="ZH-CN">适配器和使用</font>16<font lang="ZH-CN">位、</font>24<font lang="ZH-CN">位和</font>32<font lang="ZH-CN">位图象深度提供成千上万种颜色的真彩色适配器。</font>DrawDib<font lang="ZH-CN">函数组还使用了受限制的潜在能力提高了图象在显示适配器上的速度和质量。例如,当使用</font>8<font lang="ZH-CN">位的显示适配器时,</font>DrawDib<font lang="ZH-CN">函数组有效地将真彩色图象抖动为</font>256<font lang="ZH-CN">色;同样的,使用</font>4<font lang="ZH-CN">位的显示适配器时,它们也将</font>8<font lang="ZH-CN">位深度的图象抖动成</font>4<font lang="ZH-CN">位。</font></li>
<li> <font lang="ZH-CN">图象拉伸。正如</font>StretchDIBits<font lang="ZH-CN">一样,</font>DrawDib<font lang="ZH-CN">函数组用源矩形和目的矩形来控制一个图象显示的部分。可以通过改变源矩形和目的矩形的位置和大小来裁剪一幅图象不需要的部分和拉伸某部分。如果显示驱动不支持图象拉伸,那么</font>DrawDib<font lang="ZH-CN">函数组提供了比</font>StretchDIBits<font lang="ZH-CN">函数更有效的拉伸能力。</font></li>
<li> <font lang="ZH-CN">压缩图象。</font>DrawDib<font lang="ZH-CN">函数组支持好几种压缩和解压方法,其中包括游程编码,</font>JPEG,Cinepak,411YUV<font lang="ZH-CN">和</font>Indeo™<font lang="ZH-CN">。</font></li>
</ul>
</div>
<p align="left">DrawDib<font lang="ZH-CN">的操作</font></p>
<p align="left"> <font lang="ZH-CN"> 通过使用</font>DrawDibOpen<font lang="ZH-CN">函数初始化</font>DrawDib<font lang="ZH-CN">函数组。</font>DrawDibOpen<font lang="ZH-CN">负责装载动态连接库</font>(DLL)<font lang="ZH-CN">,申请内存资源,</font>DrawDib<font lang="ZH-CN">设备环境</font>(DC)<font lang="ZH-CN">,并且维持初始化相关的设备环境计数。</font>DrawDibOpen<font lang="ZH-CN">同时返回一个其它</font>DrawDib<font lang="ZH-CN">函数所需要使用的新的</font>DC<font lang="ZH-CN">句柄。</font></p>
<p align="left"> <font lang="ZH-CN"> 当使用完</font>DrawDib
DC<font lang="ZH-CN">后,可以用</font>DrawDibClose<font lang="ZH-CN">函数释放它。</font>DrawDibClose<font lang="ZH-CN">同时减少存取</font>DLL<font lang="ZH-CN">的应用的计数。在应用程序中,</font>DrawDibClose<font lang="ZH-CN">函数应是最后的</font>DrawDib<font lang="ZH-CN">操作。</font></p>
<p align="left"> <font lang="ZH-CN"> 可以创建任意多的</font>DrawDib
DC<font lang="ZH-CN">,也可以同时使用多个</font>DrawDib DC<font lang="ZH-CN">来绘制几幅位图。在应用程序中可以创建多个不同性质的</font>DrawDib
DC<font lang="ZH-CN">,这样就可以选择最合适的</font>DC<font lang="ZH-CN">设置。例如,在同一应用程序中,创建两个不同的</font>DrawDib
DC<font lang="ZH-CN">,一个用来显示图象的正常分辨率,另一个用来显示图象的放大部分。</font></p>
<p align="left"> <font lang="ZH-CN"> 为了更有效地运行,</font>DrawDib<font lang="ZH-CN">函数组需要知道显示适配器及其驱动的信息。显示配置信息是在第一次使用包含</font>DrawDib<font lang="ZH-CN">函数组的</font>DLL<font lang="ZH-CN">时,对显示适配器通过了一系列的测试之后得到的。</font>DrawDib<font lang="ZH-CN">函数组的所有应用都要用到这个配置信息。可以通过调用</font>DrawDibProfileDisplay<font lang="ZH-CN">函数来强制重新进行这些测试。</font></p>
<p align="left"> <font lang="ZH-CN"> 通常,取得和保存显示配置是一次性的事件。如果配置信息发现在这个系统中安装了另一个显示驱动时,</font>DrawDib<font lang="ZH-CN">则重新进行测试。</font></p>
<p align="left"><font lang="ZH-CN"> </font></p>
<p align="left"><font lang="ZH-CN">图象再现</font></p>
<p align="left"> <font lang="ZH-CN"> 创建了</font>DrawDib
DC<font lang="ZH-CN">后,就可以用</font>DrawDibDraw<font lang="ZH-CN">函数将</font>DIB<font lang="ZH-CN">绘至屏幕。当在</font>8<font lang="ZH-CN">位深度的显示适配器上显示真彩色图象时,</font>DrawDib<font lang="ZH-CN">将自动地抖动图象。</font></p>
<p align="left"> DrawDib<font lang="ZH-CN">也透明地支持视频压缩器。当显示压缩位图时,可通过</font>DrawDibGetBuffer<font lang="ZH-CN">函数得到包含了解压图象数据的缓冲区。如果位图是未压缩的,则</font>DrawDibGetBuffer<font lang="ZH-CN">返回</font>NULL<font lang="ZH-CN">。在应用程序中应自己区分位图是否压缩。</font></p>
<p align="left"> <font lang="ZH-CN"> 可用</font>DrawDibUpdate<font lang="ZH-CN">宏来刷新一幅图象的整体或一部分的显示。</font></p>
<p align="left"><font lang="ZH-CN">图象序列</font></p>
<p align="left"><font lang="ZH-CN"><font lang="ZH-CN"> 当</font>DrawDibDraw<font lang="ZH-CN">函数同</font>DrawDibBegin<font lang="ZH-CN">函数一起运用时,可以显示相同尺寸和格式的位图序列。</font>DrawDib<font lang="ZH-CN">通过</font>DrawDibBegin<font lang="ZH-CN">准备绘图的</font>DrawDib
DC<font lang="ZH-CN">来提高</font>DrawDibDraw<font lang="ZH-CN">的效率。如果,应用程序没有调用</font>DrawDibBegin<font lang="ZH-CN">,那么</font>DrawDibDraw<font lang="ZH-CN">会在绘图前隐含地执行</font>DrawDibBegin<font lang="ZH-CN">。</font></font></p>
<p align="left"> DrawDibBegin<font lang="ZH-CN">给</font>DrawDibDraw<font lang="ZH-CN">提供了</font>DrawDib<font lang="ZH-CN">的</font>DC<font lang="ZH-CN">,</font>DC<font lang="ZH-CN">的句柄,</font>BITMAPINFOHEADER<font lang="ZH-CN">结构的地址和源矩形及目的矩形的尺寸。当要显示一个位图序列时,</font>DrawDibDraw<font lang="ZH-CN">要检查序列中的每幅图象的这些值。如果</font>DrawDibDraw<font lang="ZH-CN">检测到这些值有任何变化,它将隐含地再次调用</font>DrawDibBegin<font lang="ZH-CN">来调整</font>DrawDib
DC<font lang="ZH-CN">的设置。</font></p>
<p align="left"> <font lang="ZH-CN"> 当调用完</font>DrawDibBegin<font lang="ZH-CN">后,就可以指定一个或多个适当的标志来调用</font>DrawDibDraw<font lang="ZH-CN">绘制图象序列。只要</font>DC<font lang="ZH-CN">句柄未改变,就可指定</font>DDF_SAME_HDC<font lang="ZH-CN">标志;下列参数未改变,就可指定</font>DDF_SAME_DRAW<font lang="ZH-CN">标志:</font>BITMAPINFOHEADER<font lang="ZH-CN">结构的地址和源矩形及目的矩形的尺寸。</font></p>
<p align="left"> <font lang="ZH-CN"> 可以通过在</font>DrawDibEnd<font lang="ZH-CN">后跟另一个</font>DrawDibBegin<font lang="ZH-CN">调用来更新前一个</font>DrawDibBegin<font lang="ZH-CN">设置的标志。</font>DrawDibEnd<font lang="ZH-CN">清除了当前的</font>DrawDib
DC<font lang="ZH-CN">的标志和设置。后续的调用</font>DrawDibBegin<font lang="ZH-CN">将重新初始化</font>DrawDib
DC<font lang="ZH-CN">,并重新设置适当的标志和设置。然而,只要至少改变了以下任一个当前的标志设置:</font>BITMAPINFOHEADER<font lang="ZH-CN">结构的地址或是源矩形或目的矩形的尺寸,也可不使用</font>DrawDibEnd<font lang="ZH-CN">而直接调用</font>DrawDibBegin<font lang="ZH-CN">来更新一个</font>DrawDib
DC<font lang="ZH-CN">。</font></p>
<p align="left"> <font lang="ZH-CN"> 通过使用</font>DrawDibStart<font lang="ZH-CN">和</font>DrawDibStop<font lang="ZH-CN">函数,可以提高使用压缩图象的数据流操作(如回放一个视频片)的</font>DrawDibDraw<font lang="ZH-CN">的效率。</font>DrawDibStart<font lang="ZH-CN">通过发送一个消息告诉视频管理器(</font>VCM<font lang="ZH-CN">)准备</font>DrawDib
DC<font lang="ZH-CN">来接受一个图象流。当流结束时,</font>DrawDibStop<font lang="ZH-CN">发送一个消息给</font>VCM<font lang="ZH-CN">来指示它释放申请的资源。</font></p>
<p align="left"> <font lang="ZH-CN"> 需要注意的是,在应用程序中必须确定源矩形和目的矩形的宽度和高度;然而却并不需要确定这些矩形的起点。应用程序可以重新</font>DrawDibDraw<font lang="ZH-CN">中的起点坐标来使用图象的不同部分或更新显示的不同部分。</font></p>
<div align="left"></div>
<p align="left"> DrawDib<font lang="ZH-CN">函数组需要响应两条调色板消息:</font>WM_QUERYNEWPALETTE<font lang="ZH-CN">和</font>WM_PALETTECHANGED<font lang="ZH-CN">。如果应用程序未注意到调色板,就需要对这些消息都增加一个各自的消息处理。</font></p>
<p align="left"> <font lang="ZH-CN"> 通过使用</font>DrawDibRealize<font lang="ZH-CN">函数可在当前</font>DC<font lang="ZH-CN">中实现当前</font>DrawDib<font lang="ZH-CN">的调色板。应当在响应</font>WM_QUERYNEWPALETTE<font lang="ZH-CN">和</font>WM_PALETTECHANGED<font lang="ZH-CN">消息时,或在用</font>DrawDibDraw<font lang="ZH-CN">函数显示一个图象序列的准备过程中实现调色板。</font></p>
<p align="left"> <font lang="ZH-CN"> 可以用</font>DrawDibSetPallette<font lang="ZH-CN">函数用另一个调色板的映射来绘一幅图象。</font>DrawDibSetPallette<font lang="ZH-CN">强迫</font>DrawDib
DC<font lang="ZH-CN">使用指定的调色板,而这会影响到图象的质量。例如,一个注意调色板的应用程序,可能已经实现了一个调色板并需要阻止</font>DrawDib<font lang="ZH-CN">实现它自己的调色板。应用程序可以通过</font>DrawDibSetPalette<font lang="ZH-CN">来通知</font>DrawDib<font lang="ZH-CN">调色板的使用。</font></p>
<p align="left"> <font lang="ZH-CN"> 通过使用</font>DrawDibGetPallette<font lang="ZH-CN">函数可以获得当前前景调色板的一个句柄。如果应用程序使用了当前前景调色板,它并没有对调色板的完全使用权,另一个应用程序能够使这个调色板句柄无效。当使用完毕后,应用程序不应该释放调色板,那样会使另一个应用程序不能使用调色板。</font></p>
<p align="left"> <font lang="ZH-CN"> 通过使用</font>DrawDibChangPallete<font lang="ZH-CN">函数可以为它的调色板</font>DrawDib<font lang="ZH-CN">来接收新的颜色值。在紧跟</font>DrawDibChangPallete<font lang="ZH-CN">的后面的代码里,可以为调色板颜色表指定新的值。当调用</font>DrawDibChangPalette<font lang="ZH-CN">时,在</font>DrawDib
DC<font lang="ZH-CN">中未设置</font>DDF_ANIMATE<font lang="ZH-CN">标志的话,可以通过使用</font>DrawDibRealize<font lang="ZH-CN">来实现调色板和</font>DrawDibDraw<font lang="ZH-CN">重绘图象来实现调色板的改变。如果</font>DDF_ANIMATE<font lang="ZH-CN">标志在</font>DrawDib
DC<font lang="ZH-CN">中设置了,就可以通过</font>DrawDibDraw<font lang="ZH-CN">或</font>DrawDibRealize<font lang="ZH-CN">来实现调色板和显示着的位图颜色的动画。通过</font>DrawDibEnd<font lang="ZH-CN">和</font>DrawDibBegin<font lang="ZH-CN">可以</font>DDF_ANIMATE<font lang="ZH-CN">标志。</font></p>
<p align="left"> <font lang="ZH-CN"> 如果释放了被选入</font>DC<font lang="ZH-CN">的</font>DrawDib<font lang="ZH-CN">调色板,</font>DC<font lang="ZH-CN">使用调色板时会报告一个</font>GDI<font lang="ZH-CN">错误。相反,应该使用</font>DrawDibSetPalette<font lang="ZH-CN">改变</font>DrawDib
DC<font lang="ZH-CN">来使用省缺调色板后另一调色板。</font></p>
<p align="left"> <font lang="ZH-CN"> 由于以下函数会释放</font>DrawDib<font lang="ZH-CN">调色板,所以,除非调色板不被</font>DC<font lang="ZH-CN">选中不应使用:</font>DrawDibEnd,DrawDibClose<font lang="ZH-CN">和</font>DrawDibBegin<font lang="ZH-CN">。同样的,当使用了相同的</font>DrawDib
DC<font lang="ZH-CN">,但指定了不同的绘制参数(</font>lpbi,dxDst,dyDst,dxSrc<font lang="ZH-CN">或</font>dySrc<font lang="ZH-CN">)或不同格式时,</font>DrawDibDraw<font lang="ZH-CN">也会释放调色板。</font></p>
<p align="left"><font lang="ZH-CN">时间计算</font></p>
<p align="left"> <font lang="ZH-CN"> 作为调试应用程序的一部分,调用</font>DrawDibTime<font lang="ZH-CN">函数可以得到一些关于完全重复特定次数</font>DrawDib<font lang="ZH-CN">操作所需时间。</font>DrawDibTime<font lang="ZH-CN">返回以下操作的时间:</font></p>
<div align="left">
<ul>
<li><font lang="ZH-CN">绘制一幅位图</font></li>
<li><font lang="ZH-CN">解压一幅位图</font></li>
<li><font lang="ZH-CN">抖动一幅位图</font></li>
<li><font lang="ZH-CN">拉伸一幅位图</font></li>
<li><font lang="ZH-CN">使用</font>BitBlt<font lang="ZH-CN">函数变换一幅位图</font></li>
<li> <font lang="ZH-CN">使用</font>StrecthDIBits<font lang="ZH-CN">函数变换一幅位图</font></li>
</ul>
</div>
<p align="left"> <font lang="ZH-CN"> 得到返回值后,</font>DrawDibTime<font lang="ZH-CN">重新设置每项操作的计数和值。</font></p>
<p align="left"> <font lang="ZH-CN"> 注意,</font>DrawDibTime<font lang="ZH-CN">只在</font>DrawDib<font lang="ZH-CN">函数的调试版中可用。</font></p>
<p align="left">DrawDib<font lang="ZH-CN">的使用</font></p>
<p align="left"> <font lang="ZH-CN"> 增加调色板消息处理</font></p>
<p align="left"> <font lang="ZH-CN"> 下面的例子说明了</font>WM_PALETTECHANGED<font lang="ZH-CN">和</font>WM_QUERYNEWPALETTE<font lang="ZH-CN">消息的处理。这个例子用了</font>DrawDibRealize<font lang="ZH-CN">函数来进行</font>WM_QUERYNEWPALETTE<font lang="ZH-CN">消息的处理。</font></p>
<p align="left"> <font lang="ZH-CN"> 应用程序应通过使目标窗口无效来让</font>DrawDibDraw<font lang="ZH-CN">函数重绘图象来响应</font>WM_QUERYNEWPALETTE<font lang="ZH-CN">消息。应用</font>DrawDibRealize<font lang="ZH-CN">函数实现调色板来响应</font>WM_PALETTECHANGED<font lang="ZH-CN">消息。</font></p>
<p align="left"> case WM_PALETTECHANGED:<br>
if ((HWND) wParam == hwnd)<br>
break;<br>
case WM_QUERYNEWPALETTE:<br>
hdc = GetDC(hwnd);<br>
f = DrawDibRealize (hdd,hdc,FALSE) > 0;<br>
ReleaseDC (hwnd,hdc);<br>
if (f)<br>
InvalidateRect ( hwnd,NULL,TRUE);<br>
break;</p>
<p align="left"> <font lang="ZH-CN"> 显示设备绘制</font></p>
<p align="left"> <font lang="ZH-CN"> 下面例子用</font>DrawDibrealize<font lang="ZH-CN">函数在显示一个位图序列之前准备</font>DrawDib
DC.</p>
<p align="left">
hdc = GetDC(hwnd);<br>
DrawDibBegin(hdd,hdc,dxDest,dyDest,lpbi,dxSrc,dySrc,NULL);<br>
DrawDibRealize(hdd,hdc,fBackground);<br>
DrawDibDraw(hdd,hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -