半透明窗体(100分)

  • 主题发起人 主题发起人 Joki
  • 开始时间 开始时间
J

Joki

Unregistered / Unconfirmed
GUEST, unregistred user!
 看到一个软件的对话框显示时是由半透明动态过渡的,像Win2000的菜单弹出时那样,
这是怎么实现的?好像牵扯到Alpha混合什么的。
 
简单说来,应该是首先在透明窗口的基础上,绘底色时,在短时内计算出过渡颜色,
动态修改底色。产生FADE IN效果。

//ALPHI混合偶不懂。
 
真正的半透明窗体只有Win2000支持.
 
>真正的半透明窗体只有Win2000支持.
95/98下不可能编出来?
 
偶是说这半透明窗体是Win2000系统建立的,不必绘制.
95/98下只能编程来画了.
 
to wint,不是alphi,是alpha(用delphi用多了,呵呵)

简单的说:

某图片的RGB值分别为 r,g,b,那么

r := r * 50/100
g := g * 50/100
b := b * 50/100

这里的 50% 就是alpha值,看出名堂了吗?
这样就半透明了嘛.
 
用控件吗?http://www.csdn.net/delphi/
VCL控件大集合-->form
看看.

 
请给我一个例子好吗?

andyyau@wx88.net
 
这个软件是SaveClean Utilities 3.0, 很多地方都有下载。
它的对话框在95/98下就有这个效果,另外foxmail3.1beta收信时弹出的窗口也是半透明的。
我想知道具体的实现方法。
 
to beta:
好像没这么简单,如果前景图片上的点颜色为(r1,g1,b1),背景图片上的点颜色
为(r2,g2,b2),透明度30%,混合的值是多少?
 
各位大虾,本人水平太差,可能问题提错了,应该是半透明面板(panel),抱歉。
 
to beta:
呵呵,绝对没有那么简单的啦!
做个比较:
<img src="http://atom.heha.net/incoming/test.gif"><img src="http://atom.heha.net/incoming/test2.gif">
From http://atom.heha.net
 
生动!
不过我的Foxmail 3.1B怎么没有什么透明效果?!
 
请看以下例子:
-------------------------------------
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Buttons;

type
TForm1 = class(TForm)
Label1: TLabel;
Shape1: TShape;
Shape2: TShape;
Shape3: TShape;
Shape4: TShape;
Image1: TImage;
SpeedButton1: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
private
{ Private declarations }
//截获背景图象
function GetBackgroundBmp:TBitmap;
//对背景图象进行滤镜处理
procedure TranslucentBmp(Bmp:TBitmap;AColor:TColor;ATransparent:Longint);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
//以下截获背景图象
function TForm1.GetBackgroundBmp:TBitmap;
var Scn:TCanvas;
h,w:Integer;
begin
Scn:=TCanvas.Create; //建立整个屏幕的画布
h:=ClientHeight; //窗口的高
w:=ClientWidth; //窗口的宽
Result.Height:=h; //设返回位图的高就是窗口的高
Result.Width:=w; //设返回位图的宽就是窗口的宽
try
Scn.Handle:=GetDC(0);//取得整个屏幕的DC
//以下一行将窗口的背景部分复制到指定的画布中,也就是本函数的返回值
Result.Canvas.CopyRect(Rect(0,0,w,h),Scn,Rect(Left,Top,Left+w,Top+h));
ReleaseDC(0, Scn.handle);
finally
Scn.Free;
end;
end;

//以下函数对背景图象进行滤镜处理,Bmp是要处理的位图;ATransparent是透明度
procedure TForm1.TranslucentBmp(Bmp:TBitmap;AColor:TColor;ATransparent:Longint);
var BkColor:COLORREF;
ForeColor:Longint;
R,G,B:Int64;
i,j:Integer;
begin
ForeColor:=ColorToRGB(AColor);
with Bmp.Canvas do
for i:=ClientHeight-1 downto 0 do
for j:=ClientWidth-1 downto 0 do
begin
BkColor:=GetPixel(Handle,j,i); //取得每一象素
R:=Byte(ForeColor)+
(Byte(BkColor)-Byte(ForeColor))*ATransparent;
G:=Byte(ForeColor shr 8)+
(Byte(BkColor shr 8)-Byte(ForeColor shr 8))*ATransparent;
B:=Byte(ForeColor shr 16)+
(Byte(BkColor shr 16)-Byte(ForeColor shr 16))*ATransparent;
SetPixelV(Handle,j,i,RGB(R,G,B));//合成象素
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var BackgroundBmp:TBitmap;
begin
try
BackgroundBmp:=Tbitmap.Create; //建立窗口背景图
BackgroundBmp.PixelFormat:=pf24bit; //指定该图是24位真彩色
BackgroundBmp:=GetBackgroundBmp; //取得窗口背景图
TranslucentBmp(BackgroundBmp,clBlack,50);//对该图象进行滤镜处理
Image1.Picture.Bitmap:=BackgroundBmp; //将处理过的图象显示出来
finally
BackgroundBmp.Free;
end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
Close;
end;

end.
-----------------------------------
另外,透明算法也可用修改图象的灰度来实现,就是把图象变暗一点。
 
就是嘛,原理挺简单的。就是把两种颜色混起来再加上或减去一个“ALPHA”值。
 
slong的算法颜色显示不正常。

alpha混合是 R1 * alpha + R2 * (1-alpha),这里0<=alpha<=1。
一般为了加快运算使alpha为整数0-256,并使用移位运算:
(R1*alpha+R2*(256-alpha)) shr 8 再将三个颜色合并。
经过验证,效果是对的。

但问题是速度仍然很慢,整个窗口完成绘制要5秒钟左右,怎样才能加快速度呢
(要动态过渡,一秒钟至少要重绘3,4次)?
 
to Joki:
>如果前景图片上的点颜色为(r1,g1,b1),背景图片上的点颜色
>为(r2,g2,b2),透明度30%,混合的值是多少?
r := r1 * 0.3 + r2 * 0.7;
就是这样啊

to Atomic:
>绝对没有那么简单的啦
就是这么简单,你好像没有理解哦
 
To beta:

这就像了啦!!!(我自己也不知道 ;-)

Thanks
 
是很简单,不过结果还是我自己找到的,谁知道快速刷新的办法,像win2000那样
那这个问题就解决了。
 
如果不想用DerictX, 不外乎是用双缓冲, scanline操作, 每次刷新不要清屏等等.
scanline操作可以提高速度几倍. 双缓冲和刷新不清屏主要不是提速, 而是减少闪烁,
让人感觉很流畅
 

Similar threads

回复
0
查看
825
不得闲
I
回复
0
查看
532
import
I
D
回复
0
查看
844
DelphiTeacher的专栏
D
D
回复
0
查看
854
DelphiTeacher的专栏
D
D
回复
0
查看
686
DelphiTeacher的专栏
D
后退
顶部