用Delphi实现位图显示特技 一、画布Tcanvas简介 在应用程序中引入位图并以多种特技显示，会使程序界面生动形象，充满魅力。Delphi中与绘图和位图操作有关的对象是画布Tcanvas。Tcanvas对象功能强大，封装了WindowsAPI的GDI，用户可以很方便地在画布上绘制直线、矩形、椭圆、多边形等基本图形，还可以显示、拷贝位图，却不必关心设备上下文等GDI概念，极大地方便了用户。Tcanvas对象本身并不是一个构件，不单独使用，它总是作为其它对象的属性来使用的。Delphi有四个对象具有画布属性，它们是TForm、TImage、TPaintbox和Tbitmap，其中前三者是可视化构件。至于Tcanvas的详细情况，可以参考Delphi的联机帮助。
实现简单的位图显示特技,实际就是以不同的方式逐渐将源位图拷贝到Tcanvas类型的对象上,如从位图的中央开始拷贝一个矩形区域到屏幕中央,矩形区域不断扩大直到拷贝整个位图,其视觉效果就是位图从屏幕中央向四周扩散。不同的拷贝方式就形成了多种特技形式,如扩散、拉动和百叶窗等。对于每种特技形式灵活运用,又可演变出多种花样,如扩散可以演变为从上向下、从左向右、从中间向四周和相反方向的扩散,以及从一角向对角方向扩散的特技花样。
实现上述位图显示特技的原理很简单，关键是怎样实现位图的拷贝。在Delphi中有两种拷贝位图的方法，相应地就有两种实现位图显示特技的方法，一种是用Tcanvas对象的方法CopyRect，另一种是调用WindowsAPI的BitBlt函数。下面就以两种特技的实现为例分别介绍这两种方法。
二、方法之一：调用CopyRect
Tcanvas对象与拷贝位图有关的是CopyMode属性和CopyRect方法，其中CopyMode定义拷贝的模式，而CopyRect执行位图拷贝的操作。当CopyMode定义为缺省值cmSrcCopy时，CopyRect将源画布上的一部分位图拷贝到目标画布上的一个矩形区域内。CopyRect的过程声明及参数意义如下：
procedureCopyRect（Dest：TRect；Canvas：TCanvas；Source：TRect）；
Dest目标画布上的矩形区域。
Canvas源画布。
Source源画布上的矩形区域。
下面以一个拉动特技的实现为例，说明如何用CopyRect方法实现特技。该例包括三个构件：Tform1、Teditl和Tbuttonl，变量step控制拉动的步骤。程序运行后，从Teditl中输入待显示位图文件名，然后单击Tbuttonl，这时位图从左侧出现并逐渐向右侧移动，好似位图被从左向右拉动一样，拉动结束后位图左上角坐标为（x0，y0）。
该例程序清单如下所示：
procedureTForml．ButtonlClick（Sender：TObject）；
const
step＝200；
x0＝20；
y0＝20；
varbitmap：tbitmap；
midx：integer；//中间变量,当前步骤所拷贝位图的宽
ratiox：real；//每步位图宽度增加量
i：integer；
rect1，rect2：trect；//源、目标矩形区域
begin
bitmap：＝tbitmap．create；
bitmap．loadfromfile（edit1．text）；
ratiox：＝bitmap．width/step；
fori：＝otostepdo
begin
midx：＝round（ratiox＊i）；
with　rect1　do
begin
left：＝bitmap．width－midx；
top：＝0；
right：＝bitmap．width；
bottom：＝bitmap．height；
end；
with　rect2　do
begin
left：＝x0；
top：＝y0；
right：＝x0＋midx；
bottom：＝yo＋bitmap．height；
end；
canvas．copyrect（rect2，bitmap．canvas，rect1）；
end；
bitmap．free；
end；
三、方法之二：调用BitBlt函数
这里涉及到了在Delphi中如何调用Windows API。每当生成一个新的项目时，Delphi自动地把WinType和WinProcs单元名添加到所生成单元文件中的uses子句中，这两个单元包含了Delphi调用Windows API所必须的类型定义和例程声明。这样，只需使用正确的参数就可以直接调用Windows API，而不需要再作其它任何声明。
BitBlt及类似的StretchBlt函数是Windows功能强大的图形处理函数，它的功能与TCanvas的CopyRect函数一样，不仅能够将位图或位图的一部分从一处拷贝到另一处，它还可以根据256个不同的光栅操作码将三幅位图结合起来，从而呈现不同的视觉效果。在WindowsAPI函数中，所有的blt函数的鼻祖都是BitBlt函数。在Delphi中BitBlt函数声明及参数意义如下：
functionBitBlt（DestDC：HDC；X，Y，nWidth，Height：Integer；SrcDC；HDC；XSrc，YSRC：Ingeger；Rop：LongInt）：Bool；
DestDC源设备上下文句柄。
X，Y源矩形左上角坐标。
nWidth，Height目标矩形的宽度和高度。
SrcDC目标矩形句柄。
XSrc，TSrc源位图矩形左上角坐标。
Rop光栅操作码。对于简单的拷贝，其值为SRCCOPY。
下面同样以一个例子来说明如何用BitBlt实现特技。本例所实现的特技是将选定的位图从屏幕中心开始向四周扩散，最后整个位图全部显示出来。此例的程序清单如下：
procedureTForm1，Button2Click（Sender：TObject）；
const
step＝200；
var
bitmap：tbitmap；
x0，y0：integer；//屏幕中心坐标
midx，midy：integer；
ratiox，ratioy：teal；
i：integer；
begin
bitmap：＝tbitmap．create；
bitmap．loadfromfile（edit1．text）；
x0：＝round（form1．width/2）；
y0：＝round（form1．height/2）；
ratiox：＝bitmap．width/step；
ratioy：＝bitmap．height/step；
fori：＝0tostepdo
begin
midx：＝round（ratiox＊i）；
midy：＝round（ratioy＊i）；
bitblt（form1.canvas.handle,x0－midx,y0－m
idy,round(ratiox＊i＊1),round(ratioy＊i＊2)
，bitmap.canvas.handle,x0－midy,y0－midy,,src
copy）；
end；
bitmap．free；
end．

(张晓辉 王孝军)