《软件报》2008年18期 邮发代号:61-74
VB具有强大的多媒体功能,许多朋友用它来制作演示程序或教学课件,但同时也有不少朋友感到困惑,那就是在进行图像显示时,VB不像Authorware、Powerpoint等软件那样,能够直观地设置各种切换转场效果。如何解决此类问题呢?相信本文中介绍的方法能给你带来一些启示!
【程序简介】
本例程序模拟了类似Powerpoint演示文稿中的切换效果,向大家展示了从上到下、从左到右、从外到内、向左旋转、垂直线、马赛克等转场特效。
1.界面设计
在程序界面设计上,主演示区为重叠的三个PictureBox控件,分别作为前台目标图片、源图片、临时用图片等;右侧功能区主要进行转场效果的设置,允许用户选择当前效果以及切换速度,其中速度值范围为1-10,值越大速度越快;另外,笔者设定了两种播放方式,即单一播放和自动循环播放,主要借助时钟控件实现(如图1)。
2.算法实现
本例程序主要应用了Windows API函数BitBlt和StretchBlt,前者的作用是将一幅位图从一个设备场景复制到另一处,在复制的过程中,允许用户指定复制的点坐标及区域尺寸等;后者的功能与前者类似,但是在复制的过程中允许对根据需要对指定位图进行伸缩处理,以实现特殊的视觉效果。具体声明和使用,请大家查阅本例源代码。
【主要代码】
1.设置初始环境
在窗体的加载事件中,首先要完成一些程序环境的设置,比如向效果列表中添加文字内容、指定初始图片等;另外还有一个十分重要的内容,即扫描当前路径下“Images”文件夹中所有图片资源,并将文件路径保存到数组中等待调用。主要代码如下:
Private Sub Form_Load()
sPic.AutoRedraw = True ‘防止源图像受前台图像影响
tempPic.AutoRedraw = True
ComboEff.AddItem "从上到下"
ComboEff.AddItem "从左到右"
………… ‘添加效果
ComboEff.AddItem "马赛克"
Call ScanPic ‘扫描图片资源
dPic.Picture = LoadPicture(PicFiles(1))
sPic.Picture = LoadPicture(PicFiles(2))
PicID = 2 ’下一张图片的序号
End Sub
Private Sub ScanPic()
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FS = FSO.GetFolder(App.Path & "\images")
ReDim PicFiles(FS.Files.Count)
i = 1
For Each F In FS.Files
PicFiles(i) = F.Path : i = i + 1
Next
End Sub
2.显示图片
前文已经提到,本例中实现了单一播放和自动循环播放两种效果,大体上都是对同一过程的调用,我们将主要代码安排在命令按钮CmdPlay的单击事件中,内容如下:
Private Sub CmdPlay_Click()
…… ‘变量声明
picWidth = sPic.ScaleWidth \ Screen.TwipsPerPixelX
picHeight = sPic.ScaleHeight \ Screen.TwipsPerPixelY
Speed = Str(TxtSpeed.Text)
If Speed < 1 Or Speed > 10 Then
Speed = 1: TxtSpeed.Text = 1 ’规范速度值
End If
Speed = Speed * 0.05
ShowEff EffID, picWidth, picHeight, Speed ‘播放转场效果
PicID = PicID + 1
If PicID > UBound(PicFiles) Then PicID = 1
sPic.Picture = LoadPicture(PicFiles(PicID))
End Sub
在上述过程的最后,程序检测当前图片序号,如果到达最末图片,则重新返回第一幅图;另外,通过时钟控件,在固定的时间内调用上述过程,即实现了图片的自动循环显示了!
3.转场效果
图片的转场效果,主要是通过调用子过程ShowEff()来实现的,该函数有四个参数:EID表示用户选择的效果编号、pw表示图片宽度、ph表示图片高度、sp表示转场速度值。在本例中,笔者一共设计了十二种转场效果,下面选择几个有代表性的加以介绍。
(1)从上到下
该效果实现的是图片从上方向下方逐行显示出来,要点是控制BitBlt函数中复制图片的高度值(代码中的变量i),主要代码如下:
For i = 1 To ph Step sp
BitBlt dPic.hdc, 0, 0, pw, i, sPic.hdc, 0, 0, SRCCOPY
Next i
根据上述原理,我们通过控制复制图片的宽度值可得到从左到右的效果,再结合数值变化反向操作,即可以实现从下到上、从右到左两种效果了。
(2)从外到内
接着上述思路,我们把图片的复制显示过程从图片的中部位置一分为二,分别使用两个BitBlt函数同步动作,并减少循环次数为原来的一半,这样便得到了从外向内展示的艺术效果,按照反方向则变为了从内到外的效果。主要代码如下:
For i = 1 To Int(ph / 2) + 1 Step sp
BitBlt dPic.hdc, 0, 0, pw, i, sPic.hdc, 0, 0, SRCCOPY
BitBlt dPic.hdc, 0, ph - i, pw, ph - i, sPic.hdc, 0, ph - i, SRCCOPY
Next i
(3)向右旋转
向右旋转的效果,模仿的是类似一个立方体在空间内的旋转,左侧图片向右侧滚动显示,同时右侧图片在逐步缩放隐去。在处理的过程中,首先将前台图片复制到临时图片框中;再利用循环结构借助StretchBlt函数,分别缩放显示源图片框和临时图片框的内容到前台图片框,形成上述旋转的动态效果。主要代码如下:
If sp < 0.5 Then sp = 0.5 ’提高显示速度
TxtSpeed.Text = 10
BitBlt tempPic.hdc, 0, 0, pw, ph, dPic.hdc, 0, 0, SRCCOPY ’保存到临时图片框
For i = 1 To pw Step sp
StretchBlt dPic.hdc, 0, 0, i, ph, sPic.hdc, 0, 0, pw, ph, SRCCOPY
StretchBlt dPic.hdc, i, 0, pw, ph, tempPic.hdc, 0, 0, pw + i, ph, SRCCOPY
Next i
而向左旋转,则是改变上述操作的运动方向,主要代码类似。
(4)上下切片
上下切片则实现了一种动感十足的效果,仿佛是两张图片前后交替错位展示出来。在代码实现上,也需要先将前台图片保存到临时图片框中;随后通过第一段循环结构,分别完成前台图片的上移、新展示图片的下移动作;当移动至图片的一半尺寸时,再通过第二段循环结构,实现前台图片下移隐去、新图片上移完整显示的动作。主要代码如下:
Temp = Int(ph / 2) ’图片尺寸的一半
BitBlt tempPic.hdc, 0, 0, pw, ph, dPic.hdc, 0, 0, SRCCOPY
For i = 1 To Temp Step sp
BitBlt dPic.hdc, 0, 0, pw, ph - i, tempPic.hdc, 0, i, SRCCOPY
BitBlt dPic.hdc, 0, ph - i, pw, ph, sPic.hdc, 0, ph - i - i, SRCCOPY
Next i
For i = 1 To Temp Step sp
BitBlt dPic.hdc, 0, Temp - i, pw, ph, sPic.hdc, 0, 0, SRCCOPY
BitBlt dPic.hdc, 0, i, pw, Temp - i - i, tempPic.hdc, 0, 0, SRCCOPY
Next i
此外,借助BitBlt函数笔者还实现了类似百叶窗效果的垂直线和平行线效果,以及较为常见的马赛克效果,由于篇幅限制,不作具体介绍,感兴趣的朋友可以参阅本例程序的源代码。
|