如何实现photoshop的透明效果(100分)

  • 主题发起人 主题发起人 周卿锦
  • 开始时间 开始时间

周卿锦

Unregistered / Unconfirmed
GUEST, unregistred user!
如何实现photoshop的透明效果,各位大侠如果你们知道,把答案给我一份,我的地址是
zhou-pc@163.net。企盼佳音,谢谢!
 
请写出具体要求,以便回答。。。
 
就是可以将一张图按一定透明度透明到指定的位置。
 
win2k解决方法:
半透明窗体并不是win2000的新特效,凡是用过金山词霸的同志都会发现在屏幕取词
设置中有一个半透明背景的选项,这说明在win98下是可以实现半透明窗口的。但我
还是要首先谈谈在win2000实现半透明窗体的新函数setlayeredwindowattributes。利
用这个函数就可以轻松创建一个半透明窗体,但是利用这个函数的程序编译后在win98
下是无法运行的。 setlayeredwindowattributes api函数介绍如下: 函数功能:设置
窗口透明颜色 参数:setlayeredwindowattributes( hwnd hwnd, //窗口手柄 colorref
crkey, //指定颜色值 byte balpha, //混合函数值 dword dwflags //动作 参数解释:
hwnd:窗口句柄。当使用createwindowex函数创建窗口时,窗口由ws_ex_layered指定的
值创建;或者窗口已经创建后,由setwindowlong根据ws_ex_layered指定的值改变。 cr
key:指向一个color值,该值指定一个透明颜色值,当创建窗口时,窗口将使用该值。 b
alpha:混合函数值。该值用于描述窗口的不透明度。当balpha 值为0时,窗口完全透明
,当balpha值为255时,窗口完全不透明。 dwflags:指定动作。这个参数可以取一个或
多个值。用它我们可以创建一个不规则的窗体。 setlayeredwindowattributes函数的ap
i声明: setlayeredwindowattributes(hwnd: hwnd; crkey: dword;balpha: byte; dwflag: dword): boolean; stdcall; ---------程序代码1: const ws_ex_layered = $80000; lwa_colorkey = $1; lwa_alpha = $2; procedure tform1.formcreate(sender: tobject); var l:longint; begin l :=getwindowlong(handle, gwl_exstyle); l := l or ws_ex_layered; setwindowlong (handle, gwl_exstyle, l); setlayeredwindowattributes(handle, 180, 120, lwa_alpha); end; 还有一些其它的常量定义如: ac_src_alpha = $1; ac_dst_no_premult_alpha = $10; ulw_colorkey = $1; ulw_alpha = $2; ulw_opaque = $400; 等还要参看msdn。有些我还没有搞明白,如果哪位同志知道的话,请告诉我。 那么在win98下又是如何实现半透明窗体的呢?其基本原理是:在窗口显示前其获取背景图然后对背景图象进行滤镜效果处理再将处理过的背景图象显示在窗口前面。 有一种方法是:首先,做出一个透明窗体,然后在窗体上添加一个shape,将其扩展至全屏幕,将shape的pen的mode属性设为pmmask,pen的style属性设为psclear,最后改变brush的color属性即可。 因为没有api支持,win9x下只能模拟,效果不太好,就象金山词霸的取词窗口,背景改变而窗体上还是不变。但我们可以利用timer控件来解决窗体的刷新率和时时更新的问题。 不过听说“金山词霸的半透明窗口效果只能在带mmx指令集的处理器中才起作用”不知是真是假,由于手头没有这样的电脑,还请同志们自己验证吧。
 
给你发了个例子,看看吧!
 
各位大侠,我要做的是photoshop里的透明效果,就是可以将一张图按一定透明度透明到指定的位置。
我用了一个API函数Alphablend但是这个函数不能控制透明度,Help me!!!
 
你要的透明度是由你自行指定还是根据图片本身的Alpha 值或 亮度值?
 
自行指定。
 
BkGround 背景
FrGround 前景 left,top 前景混合左上角位置
Alpha 0..255

Procedure BlendBmp(BkGround,FrGround:TBitmap;Left,Top,Alpha:Integer);
Var X,Y:Integer;
PB,PF:PbyteArray;
R1,R2,G1,G2,B1,B2:Integer;
Begin
BkGround.PixelFormat:=pf24bit;
FrGround.PixelFormat:=pf24bit;
For Y:=Top to BkGround.Height-1 do
Begin
IF Y-Top>FrGround.Height-1 then Break;
PB:=BkGround.ScanLine[Y];
PF:=FrGround.ScanLine[Y-Top];
For X:=Left to BkGround.Width-1 do
Begin
IF X-Left>FrGround.Width-1 then Continue;
B1:=PB[X*3]; G1:=PB[X*3+1]; R1:=PB[X*3+2];
B2:=PF[(X-left)*3]; G2:=PF[(X-left)*3+1]; R2:=PF[(X-left)*3+2];
PB[X*3]:=(B2*Alpha+B1*(255-Alpha)) div 255;
PB[X*3+1]:=(G2*Alpha+G1*(255-Alpha)) div 255;
PB[X*3+2]:=(R2*Alpha+R1*(255-Alpha)) div 255;
End;
End;
End;
 
奇怪!Delphi5 附加的 Win32 HELP 找不著此 API ,
不知要去哪裡更新,或下載新系統新增之 API 說明?
 
GGCAT大侠,我要做的是将一张图片弄透明(按一定透明度),然后显示在指定的位置上去。
你的想法虽然很好,但如果背景图是不断变化的呢?
jiichen,在Delphi5 附加的 Win32 HELP 确实找不著此 API函数Alphablend,在vc++ 附加
的 Win32 HELP 可以找到,或在微软的英文站点用搜索引擎也可以找得到。可是这函数实现
不了透明度,如果将透明区域不断刷新,会产生严重的闪烁。我用该函数做了如下的单元,
只是该函数的参数意义我还不太清楚,并且当sourcehdc对应的图片位置不完全在窗体里时或
在内存中,该函数就不起透明作用了。
unit transparent;

interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
procedure trasparenthdc(desthdc:hdc;destleft:integer;desttop:integer;destwidth:integer;destheight:integer;sourcehdc:hdc;sourceleft:integer;sourcetop:integer;
sourcewidth:integer;sourceheight:integer;tansparentpacent:integer);
implementation



procedure trasparenthdc(desthdc:hdc;destleft:integer;desttop:integer;destwidth:integer;
destheight:integer;sourcehdc:hdc;sourceleft:integer;sourcetop:integer;sourcewidth:integer;sourceheight:integer;tansparentpacent:integer);
var
tran:blendfunction;
begin
tran.blendop:=ac_src_over;
tran.blendflags:=0;
tran.sourceconstantalpha:=round((tansparentpacent*255)/100);
tran.alphaformat:=0;
alphablend(desthdc,destleft,desttop,destwidth,destheight,sourcehdc,sourcetop,sourceleft,
sourcewidth,sourceheight,tran);
end;


end.
 
TO 周卿锦:
在背景图片变化后再应用一次就可以了。
而你理想中的情况是不存在的,你想建立一个自己透明的层在桌面上,自动
透出他下面的一切。要知道,在我们的眼中,各个窗口固然有层次关系,互相
重叠,而实际上,windows 在绘制时只是考虑每个窗口暴露在外的部分,也就是
说,对于被你的层所覆盖的东西,并没有绘制,那你又如何合成呢?
 
GGCAT大侠,其实Alphablend的效果很不错,只不过不知道它的内在原理,可惜一点的是
不能控制透明度。像你所说的方法还不能完全实现我所需要的效果。还有你能不能教我一些关
于图象方面的知识,最好是一些图象处理技巧和函数,谢谢!
 
透明的原理在我开始提供的函数里很清楚,而且我也用了 Alpha Blend 效果很好。
例: 在 Form 里放两个 image , 各载入一个 bmp , 再放一个trackBar ,Max=255
定义一全局Tbitmap 作为目标的备份;
Var TB:TBitmap;
Form.OnCreate
Begin
TB:=Tbitmap.Create;
TB.Assign(Image2.Picture.Bitmap);
End;

procedure TForm1.TrackBar1Change(Sender: TObject);
var
tran:blendfunction;
desthdc,sourcehdc:Hdc;
begin
Image2.Picture.Bitmap.Assign(TB);
DestHdc:= Image2.Picture.Bitmap.canvas.Handle;
SourceHdc:=Image1.Picture.Bitmap.Canvas.Handle;

tran.blendop:=ac_src_over;
tran.blendflags:=0;
tran.sourceconstantalpha:=TrackBar1.Position;;
tran.alphaformat:=0;

Alphablend(desthdc,0,0,200,200,sourcehdc,0,0,
200,200,tran);
Image2.Refresh;
End;
拖动 TrackBar ,你可以看到柔和的透明变化,也没有闪烁,而且这个
blend 是在 Bitmap 的Dc 里进行,是不可见的,最后通过 Refresh 才
体现在桌面。还有Any Problem?

 
GGCAT大侠,其实只要有了不断刷新,比较大的图片都会出现严重的闪烁。以前我也
是想要用刷新来实现,因为出现严重的闪烁,所以放弃了。
我要做的效果是Adobe Photoshop下的window选项的hide layers里的opacity属性那
样的效果。
 
I 服了 you ,
你试一下我 给你的 程序,看看有没有闪烁。
 
对了,那句该成:

Alphablend(desthdc,0,0,image2.picture.bitmap.width,image2.picture.bitmap.Height,sourcehdc,0,0,
image1.picture.bitmap.width,image1.picture.bitmap.height,tran);

免得大小超出画不出来。
 
你的程序我试过了,跟我以前的情况差不多,闪烁的厉害。
 
GGCAT大侠,你的程序确实运行得很好。早上我试运行时将目标区域的画布
设得比其本身的图片还大,因此出现了闪烁,让大侠见笑了,不好意思。但是
我要的效果还没有完全达到,先暂时给你记上50分到时在奉上。
 
GGCAT大侠,你最初提供的函数怎么用,我按照参数赋值,却没有什么效果,为什么呢?
麻烦帮我解答一下,或给一个例子也行,谢谢。
 
后退
顶部