快速简单地实现淡入淡出效果(0分)

  • 主题发起人 主题发起人 笑西风
  • 开始时间 开始时间

笑西风

Unregistered / Unconfirmed
GUEST, unregistred user!
  在应用程序中引入图片淡入及淡出,可以让用户界面更加美观。
以前报刊杂志中介绍的常用方法有两种:一是自己写程序,诸个象素
进行混合渐变;二是使用DirectX,建立一个带Alpha通道的Surface。
第一种,效果可以自己控制,但比较麻烦,而且一般不容易生成硬件优化的代码;
第二种速度很快,却需要使用DirectX库。其实何必舍近求远呢?在
Windows的GDI中已经提供了一个很好的API――AlphaBlend让我们使用,
既保证速度又很简单,本文就详细介绍如何使用它。

  这里用Delphi 4.0讲解方法,因为在Delphi中声明和使用Windows API很方便。
在Delphi 4.0 Source目录下的Windows.pas中,已经有了AlphaBlend的声明,
但Delphi却把它认作是GDI32.dll提供的函数,其实微软把它放到了msimg32.dll
这个动态库中,因此直接使用AlphaBlend后,编译运行会产生一个引用错误,必须
自己来声明一个新函数,这里我们用AlphaBlendA来引用:(此问题在Delphi 6.0中已解决)
type // Delphi的声明段中加上以下一行
function AlphaBlendA(DestDC: HDC; TopDest, LeftDest, WidthDest, HeightDest: Integer;
SrcDC: HDC; TopSrc, LeftSrc, WidthSrc, HeightSrc: Integer;
BlendFunction: TBlendFunction): BOOL; stdcall; // API函数声明

implementation // Delphi的实现段中加上以下一行

function AlphaBlendA; external 'msimg32.dll' name 'AlphaBlend'; // 实现函数
其中DestDC参数是生成画面的Handle,在Delphi中一般是Canvas.Handle,TopDest,
LeftDest, WidthDest, HeightDest是生成画面的右上角坐标和长宽值;SrcDC, TopSrc,
LeftSrc, WidthSrc, HeightSrc表示原图的相关参数,因为AlphaBlend会自动处理缩放,
所以WidthDest, Height, LeftSrc, WidthSrc可以为不同值;DestBlendFunction是控制
Alpha混合的结构。
DestBlendFunction这个结构,是AlphaBlend的使用中最重要的参数,它的定义如下:
typedef struct _BLENDFUNCTION
{
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;
BlendOP是混合方式,当前只有AC_SRC_OVER一种,即将SrcDC放置于DstDC之上,进行混合;
BlendFlags必须为零,为什么呢?M$没有告诉我们。
SourceConstantAlpha控制SrcDC画面的透明度,为0时,完全透明;为255时,完全不透明,
其间逐渐变化。
AlphaFormat表示SrcDC和DstDC的格式,一般不用指定。

为了避免动态生成的麻烦,我们直接放两个Image控件在Form上,Image1先调入一幅BMP图
片,Image2则设好大小即可。再放两个Button上去,Caption各设为“淡入”和“淡出”,
接下来,写按钮事件即淡入淡出效果处理:
procedure TForm1.Button1Click(Sender: TObject); // 淡入效果
var
sBlendFunction: BlendFunction; // 这是Alpha混合时需要的一个类型参数
i: byte; // 循环变量
begin
Button1.Enabled := False; // 暂停“淡入”按钮输入
with sBlendFunction do // 设置初值
begin
BlendOp := AC_SRC_OVER; // 目前唯一支持的一种混合方式
BlendFlags := 0; // 必须为零
AlphaFormat := 0 // 缺省
end;
for i := 0 to 51 do // 共有51帧
begin
sBlendFunction.SourceConstantAlpha := i * 5; // 从全透明到不透明,每次渐变5级
AlphaBlendA(Image2.Canvas.Handle,0,0,
Image2.Width,Image2.Height,Form1.Canvas.Handle,
Image1.Top,Image1.Left, Image1.Width,Image1.Height,
sBlendFunction); // Alpha混合处理
sleep(10); // 延时10毫秒,适当的延时可让效果看起来更逼真
Image2.Refresh // 一定要实时刷新Image2,才能看出变化
end;
Button2.Enabled := True // 允许“淡出”按钮的输入
end;

而在淡出效果(即Button2的处理)中,只要将背景底色中的一块作为原图即可:
AlphaBlendA(Image2.Canvas.Handle,0,0,
Image2.Width,Image2.Height,Form1.Canvas.Handle,290,250,
20,20,sBlendFunction);// (290,250,310,270)区域为底色
以上程序在Windows 98,Inprise Delphi 4.0 Update Pack 3下运行通过。
利用AlphaBlend还可以产生其它图象效果,比如将SourceConstantAlpha适当居中,
能象PhotoShop一样出现“浮雕”的效果等。
在msimg32.dll中,除了AlphaBlend,还有TransparentBlt和GradientFill等很有用
的API:TransparentBlt可以快速处理16色和256色的透明贴图(AlphaBlend可以处理
32位色);GradientFill则能够借助硬件加速,产生颜色渐变的三角形或矩形,利用
上它们,将会让你编写的程序更加吸引人。
 
笑兄弟,很热心公益哦
 
呵呵,如楼上所说,3x
 
让我试试速度
 
接受答案了.
 
为什么我在win2000+Delphi5中编译通过,但运行后执行事件时出现
“Access violation at address 00EB0000,Read of address 00EB0000.”的错误呢?
 
打开调试器,跟踪瞧一下,执行到哪里出错?
 
后退
顶部