Chinaunix首页 | 论坛 | 博客
  • 博客访问: 293284
  • 博文数量: 34
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 433
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-23 13:16
文章分类

全部博文(34)

文章存档

2011年(3)

2010年(4)

2009年(6)

2008年(21)

我的朋友

分类:

2008-08-15 16:18:14

    在用Visual Basic编程的时候,通常要调用图片,如果图片出现的时候是以各种完美的效果出现的,(如马赛克效果,百叶窗效果等)则你的程序就会显得更加灵活,你的程序就会更加专业化。本文讲述了Visual Basic中如何调用API函数,以及用API函数中的BitBlt函数实现各种完美的图片出现效果的过程。

§1 一般的图片出现效果

    一般情况下,要使Visual Basic中的图片出现,例如,要显示Picture1中的图片,只需一句代码:

    Picture1.Visible=True
 
  使用以上方法时,图片是突然出现的。也可以编复杂一点的代码,使图片从左到右、从上到下或从中间向四周扩大。例如,使Picture1中的图片从左到右出现,其代码为:

    Picture1.Width = 0
    Picture1.Visible = True
    For i = 0 To 5000 Step 50 //5000代表图片的高度
        Picture1.Width = i
    Next i

  使Picture1中的图片从上到下出现的代码为:

    Picture1.Height = 0
    Picture1.Visible = True
    For i = 0 To 4000 Step 40 //4000代表图片的宽度
        Picture1.Height = i
    Next i

    使Picture1中的图片从中间向四周扩大的代码为:

    Picture1.Width = 0
    Picture1.Height = 0
    Picture1.Visible = True
    For i = 0 To 100
        Picture1.Width = Picture1.Width + 50
        Picture1.Height = Picture1.Height + 40
        Picture1.Left = Picture1.Left - 100
        Picture1.Top = Picture1.Top - 80
    Next i


  当然,你可以灵活地应用以上办法实现其他更加好看的图片出现效果。然而,同Authorware等其他软件编制的程序相比,你的图片出现效果仍然会黯然失色,因为Authorware编程时,可以很容易地实现从上到下、从左到右、百叶窗、开门、关门等完美的图片出现效果,要在Visual Basic中做到这些效果并非易事。

  但“天无绝人之路”,强大的Windows API函数中的BitBlt函数将帮助您实现这一愿望。

§2 BitBlt函数

一、 BitBlt函数的功能

  BitBlt API函数的功能是将屏幕上任何一块拷贝到屏幕上其它任何一个地方。

二、 声明BitBlt函数

  1. 运行Visual Basic4.0程序组中的API Text Viewer程序项。

  2. 在API Text Viewer中,单击File菜单下的Load Text File...命令。

  3. 在出现的Select a Text API File对话框中,选择Win32api.txt文件。

  4. 为了使以后拷贝Windows API函数更快,你可以将Win32api.txt文件转换成为一个数据库。如图,单击“是(Y)”。

  5. 在API Type下拉框中选择Declare。

  6. 在Available Items中选择BitBlt,如图,单击Add按纽,于是BitBlt便出现在Selected Items框中,单击Copy按纽。BitBlt函数变拷贝到剪贴板上。

  7. 关闭API Text Viewer,打开Visual Basic程序,使用Insert菜单下的Module命令新建一个Module1,使用Edit菜单下的Paste命令,将剪贴板上的BitBlt函数拷贝到Module1中。这样,在您的程序中,就可以使用BitBlt函数了。

三、BitBlt函数中各参数简介

  Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

  以上是BitBlt函数的声明格式,其中,各参数定义如下:

        参数        描述
    hDestDC      接收位图的设备描述表
    X            目标矩形左上角的逻辑X坐标
    Y            目标矩形左上角的逻辑Y坐标
    nWidth       目标矩形的宽度
    nHeight      目标矩形的高度
    hSrcDC       源设备描述表
    xSrc         源位图左上角的逻辑X坐标
    ySrc         源位图左上角的逻辑Y坐标
    dwRop        拷贝模式

dwRop的各种可能值为:

    &HCC0020    dest=source
    &HEE0086    dest=source OR dest
    &H8800C6    dest=source AND dest
    &H660046    dest=source XOR dest
    &H440328    dest=source AND (NOT dest)
    &H330008    dest=not source
    &H1100A6    dest=(NOT source)AND(NOT dest)
    &HC000CA    dest=source AND pattern
    &HBB0226    dest=(NOT source) OR dest
    &HF00021    dest=pattern
    &HFB0A09    dest=Dpsnoo
    &H5A0049    dest=pattern XOR dest
    &H550009    dest=NOT dest
    &H42&       dest=BLACK
    &HFF0062    dest=WHITE

  在本程序中使用的BitBlt函数均定义dwRop=HCC0020,如果你定义dwRop为其他值,会收到其他异想不到的效果。

§3 用BitBlt函数实现各种各样的图片出现效果

  实现各种各样的图片出现效果,有两张图片Picture1和Picture2,在Picture1中装入要显示的图片,(可以在窗体设计时就装好,也可以在程序运行过程中装入。)将Picture1中的图片以各种方法拷贝到Picture2中,从而实现各种各样的图片出现效果。

  先在Picture1中装入待显示的图片,并设置Picture1的属性为AutoRedraw=True,Visible=False, 设置Picture2的属性为AutoRedraw=False,Visible=True,设置Form的属性为ScaleMode=3。

一、从上到下效果

  将Picture1从形式上分为很多小块

  如图所示,要将Picture1中的图片拷贝到Picture2中,首先将Picture1从形式上划分为很多小块a1、a2、a3、…,每块宽度为。

  然后利用BitBlt函数先将Picture1中的a1块拷贝到Picture2中的相同位置,等待片刻,再拷贝a2块、a3块、…直到。如果将取得足够小,则人眼看到 Picture2中的图片就是以从上到下的效果出现的。其程序如下:

    Picture2.Cls
    nHeight = 3  //小块的高度,即
    Stripes = Picture1.Height / nHeight‘总共的小块数目n个
    P2 = nHeight
    P1 = Picture1.Width

    For I = 0 To Picture1.Height Step nHeight
        p3 = I
        r% = BitBlt(Form1.Picture2.hDC, 0, p3, P1, P2, Form1.Picture1.hDC, 0, p3, &HCC0020)
        For j = 1 To 8000 //等待片刻,图片从上到下出现的时间可以由此调节
        Next
    Next

  明白了以上制作原理以后,图片从下到上、从做到右、从右到左出现的效果也就可以实现了。

二、开门效果

  开门效果的制作也是先将Picture1从形式上划分为很多小块a1、a2、a3、…,每块宽度为。

  然后利用BitBlt函数先将Picture1中的a0块拷贝到Picture2中的相同位置,等待片刻,再拷贝a1块、a2块、…直到。如果将取得足够小,则人眼看到 Picture2中的图片就是以开门的效果出现的。其程序如下:

  Picture2.Cls
  nWidth = 3‘小块的宽度,即
  Stripes = Picture1.Width / nWidth‘总共的小块数目n个
  P2 = Picture1.Height
  P1 = nWidth
  For I = Picture1.Width / 2 + nWidth To 0 Step -nWidth
    p3 = I
    p4 = Picture1.Width - I
    r% = BitBlt(Form1.Picture2.hDC, p3, 0, P1, P2, Form1.Picture1.hDC, p3, 0, &HCC0020)
    r% = BitBlt(Form1.Picture2.hDC, p4, 0, P1, P2, Form1.Picture1.hDC, p4, 0, &HCC0020)
    For j = 1 To 8000‘等待片刻,图片开门效果出现的时间可以由此调节
    Next
  Next

  根据同样的方法可以制作“上下开门”、“左右关门”、“上下关门”、“从中间向四周扩大”、“从四周向中间缩小”等效果。

三、百叶窗效果

  分成几个大块,每个大块分成很多个小块

  如图所示,要将Picture1中的图片拷贝到Picture2中,首先将Picture1从形式上划分为很多宽度为的大块,然后再将每一块进一步划分为宽度为的若干小块。

  然后利用BitBlt函数先将Picture1中的a1块拷贝到Picture2中的相同位置,再拷贝b1块、c1块、…5却??蹋?倏奖碼2块、b2块、c2块、…。如果将取得足够小,则人眼看到 Picture2中的图片就是以百叶窗的效果出现的。其程序如下:

  Picture2.Cls
  nWidth = 3
  mWidth = 18
  Stripes = Picture1.Width / nWidth
  P2 = Picture1.Height
  P1 = nWidth
  For j = 0 To mWidth Step nWidth
    For I = 0 To Picture1.Width + nWidth Step mWidth
      p3 = I + j
      r% = BitBlt(Form1.Picture2.hDC, p3, 0, P1, P2, Form1.Picture1.hDC, p3, 0, &HCC0020)
    Next
    For k = 1 To 200000
    Next
  Next

根据同样的道理,可以制作上下百叶窗效果。


四、逐段翻开效果

  分成几个大块,每个大块分成很多个小块

  如图所示,要将Picture1中的图片拷贝到Picture2中,首先将Picture1从形式上划分为很多宽度为的大块,然后再将每一块进一步划分为宽度为的若干小块。

  然后利用BitBlt函数先将Picture1中的a0块拷贝到Picture2中的相同位置,再拷贝a1块、a2块、…。等待片刻,再拷贝b0块、 b1块、b2块、…。如果将取得足够小,则人眼看到 Picture2中的图片就是以逐段翻开的效果出现的。其程序如下:

  stripewidth = 40
  Stripes = Picture1.ScaleWidth / stripewidth
  P2 = Picture1.ScaleHeight
  For i = 0 To (Stripes - 1) / 10 Step 1
    For m = 0 To stripewidth / 2
      r% = BitBlt(Picture2.hDC, P1 + m + stripewidth / 2 + i * stripewidth, 0, 2, P2, Picture1.hDC, P1 + m + stripewidth / 2 + i * stripewidth, 0, &HCC0020)
      r% = BitBlt(Picture2.hDC, P1 - m + stripewidth / 2 + i * stripewidth, 0, 2, P2, Picture1.hDC, P1 - m + stripewidth / 2 + i * stripewidth, 0, &HCC0020)
      For j = 1 To 10000
        Next j
    Next m

    For j = 1 To 50000
      Next j

  Next i


五、逐段进入效果

将Picture1从形式上划分为很多宽度为的大块

a1块在Picture2中的位置

a1块在Picture2中的位置前进了

  逐段进入效果的制作要麻烦一些,要将Picture1中的图片拷贝到Picture2中,首先将Picture1从形式上划分为很多宽度为的大块a1、a2、a3、…。

  利用BitBlt函数先将Picture1中的a1块拷贝到Picture2中的最右边,如图(2),等待片刻,将Picture2中的图片清除掉,然后将Picture1中的a1块拷贝到Picture2中的距离最右边处。如图(3),a1块好象向左前进了,如此下去,就可以实现a1块从左进入,使用同样的办法使a2块、a3块、…依次逐渐进入。这样,人眼看到 Picture2中的图片就是以逐段进入的效果出现的。其程序如下:

  Picture2.Cls
  nWidth = 50
  Stripes = Picture1.Width / nWidth
  P2 = Picture1.Height
  P1 = nWidth

  For I = 0 To Picture1.Width + nWidth Step nWidth
    p3 = I
    For k = Picture1.Width To I Step -nWidth
      p4 = k
      Picture2.Cls

      r% = BitBlt(Picture2.hDC, 0, 0, I, P2, Picture1.hDC, 0, 0, &HCC0020)
      r% = BitBlt(Picture2.hDC, p4, 0, P1, P2, Picture1.hDC, p3, 0, &HCC0020)

      For j = 1 To 300000 注释:Wait For A While
      Next j

    Next k

  Next i


  必须指出,以上逐段进入的效果有一个明显的缺点,就是有“闪动”现象。产生这种现象的原因是由于程序不停地删除、不停地拷贝同一块造成的。如果不删除而只拷贝,则不会出现“闪动”现象。

六、马赛克效果

  马赛克效果在很多软件中都有应用,其原理是将Picture1从形式上划分为很多小块,如图所示,一共有n块。然后利用BitBlt函数将Picture1中的小块随机地拷贝到Picture2中的相同位置处。

  你不能简单地产生一个随机数,然后将这个随机数的值所对应的那一小块图片拷到Picture2中。因为随机数是随机的,所以有可能某些数重复出现,而某些数很久甚至始终未出现。这就造成Picture2中有些块被重复拷贝,而有些块始终未出现。另外,在随机拷贝的后阶段,随机数与以前重复的概率越来越大,这就造成新块出现的时间越来越慢,达不到理想的马赛克效果。

  解决的办法是先产生一个随机系列。用一维数组 B(n)记录n个随机值,每一个随机值都在n以内,且各不相同。然后按顺序将B(n)中的随机值读出,并根据这个随机值拷贝对应的图片块。这样,新块出现的速度才能做到均匀,而且保证每个图片块都能出现,从而达到非常完美的马赛克效果。

  Dim A(0 To 1000) As Integer
  Dim B(0 To 400) As Integer
  Dim S1, S2 As Integer
  Picture2.Cls

  注释:产生随机数组
  For I = 0 To 1000
    A(I) = 0
  Next

  For I = 0 To 400
    Loop1: k = Int(Rnd() * 1000) + 1
    If Not (A(k) = 0) Then GoTo Loop1
      A(k) = I
  Next

  For I = 0 To 1000
    If Not (A(I) = 0) Then
      B(V1) = A(I)
      V1 = V1 + 1
    End If
  Next

‘根据随机数组的值,拷贝小图片

  S1 = Picture1.Width / 20
  S2 = Picture1.Height / 20
  For I = 0 To 400
    k2 = B(I) Mod 20
    k1 = ((Int(B(I)) - k2) / 20) * S2
    k2 = k2 * S1
    r% = BitBlt(Picture2.hDC, k2, k1, S1 + 2, S2 + 2, Picture1.hDC, k2, k1, &HCC0020)
    For j = 1 To 5000 注释:wait
      Next
  Next

  以上程序在WIN95,VB4中运行通过,在VB3,VB5,VB6中梢加修改,也可以运行通过。图片出现的效果还有很多,限于篇幅所限,就不在这里叙述了。只要你灵活地应用以上方法,一定还能产生更多更美的图片出现效果。这些风格各异的图片出现效果必定会为您的Visual Basic程序增添美丽的情调,使您的程序更富魅力、更具专业。 
阅读(1353) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~