关于图像半透明的问题(100分)

  • 主题发起人 主题发起人 foolboy007
  • 开始时间 开始时间
F

foolboy007

Unregistered / Unconfirmed
GUEST, unregistred user!
我在《电脑爱好者》去年10期上看到一个用delphi实现半透明效果的程序。
程序中说在98下测试通过。但是,我在win2000下(我没装98),却实现不了半透明,
程序能正确编译。不知为何?请大家看看:
----------
在form上放一个计时器(命名为tmrshowbitmap, interval=20)
一个image控件(命名为imgsrc,autosize为true).
代码如下:

unit stp;

interface

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

type
TFrmsemitransparent = class(TForm)
tmrshowbitmap: TTimer;//控制透明度的时钟
Imgsrc: TImage;
procedure FormCreate(Sender: TObject);
procedure tmrshowbitmaptimer(Sender:TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure onErasebkgnd(var Message:TWMEraseBkgnd); Message WM_EraseBkgnd;//使用message关键字进行消息截获。
end;

var
Frmsemitransparent: TFrmsemitransparent;
bf:_blendfunction;//alpha透明结构函数
nwidth:integer;
nheight:integer;
ncount:integer;
implementation

{$R *.DFM}
procedure TfrmSemiTransparent.onEraseBkgnd(var Message:TWMEraseBkgnd);
begin
Message.Result:=1;
end;

procedure Tfrmsemitransparent.tmrshowbitmaptimer(sender:Tobject);
begin
ncount:=nCount+1;
if nCount>250 then
begin
tmrshowbitmap.enabled:=false;
frmsemiTransparent.Hide ;
frmsemiTransparent.Close;
end;
bf.SourceConstantAlpha:=ncount;
Alphablend(frmsemitransparent.canvas.handle,
0,0,nwidth,nheight,imgsrc.canvas.handle,
0,0,nwidth,nheight,bf);
end;
procedure TFrmsemitransparent.FormCreate(Sender: TObject);
begin
frmsemitransparent.BorderStyle:=bsnone;
frmsemitransparent.Position:=podesktopcenter;
nwidth:=imgsrc.width;
nheight:=imgsrc.height;
ncount:=0;

bf.blendop:=ac_src_over;
bf.blendflags:=0;
bf.sourceconstantalpha:=ncount;
bf.alphaformat:=0;

setwindowpos(handle,hwnd_top,0,0,nwidth-1,nheight-1,0);
tmrshowbitmap.enabled:=true;
end;

end.
 
可能和你的硬件有关。另外,就这些能正确编译吗?
 
没问题
有exe文件
能显示图片,但不半透明
 
form1.Alphablend:=true;
form1.Alphablendvalue:=230;
 
无法编译通过。
 
没有必要那么麻烦,首先设置form的alphablend:=true;
然后随便控制alphablendvalue的值,0-255,调整透明度,0完全不见,255完全可见。
 
请各位看明白,是图像半透明
而不是窗体半透明,我那个代码运行出来根本就没有窗体!!
 
有一种折中的效果,就是取奇数行或者偶数行,剩下的行用白色代替看看下面的代码!
procedure TMainForm.partalphaClick(Sender: TObject);
var
bmp: Tbitmap;
i, j: Integer;
p: pbytearray;
begin
bmp := Tbitmap.Create;
bmp.Assign(childform.image1.Picture.Bitmap);
bmp.PixelFormat := pf24bit;
bmp.Height := childform.image1.Picture.Bitmap.Height;
bmp.Width := childform.image1.Picture.Bitmap.Width;
i := 0;
while i < bmp.Height - 2 do
begin
p := bmp.ScanLine;

for j := 0 to bmp.Width - 1 do
begin
p[3 * j + 2] := 255;
p[3 * j + 1] := 255;
p[3 * j] := 255;
end;
i := i + 2;
end;
childform.image1.Picture.Bitmap.Assign(bmp);
bmp.free;
 
假定image1是你的图片,image1放在form1上则:
image1.align:=clClient;
form1.BorderStyle:=bsNone;
form1.Alphablend:=true;
form1.Alphablendvalue:=150;
你再看看效果吧
 
bluemasker:
哈哈,太妙了。
 
To bluemasker: 不好意思 程序还是无法编译
你用的是D5吗?
我的这个版本中form怎么没有你说的那两个alpha的属性??
image也没有alpha属性,只有transparent属性
 
d5下:
const
WS_EX_LAYERED = $80000;

AC_SRC_OVER = $0;
AC_SRC_ALPHA = $1;
AC_SRC_NO_PREMULT_ALPHA = $1;
AC_SRC_NO_ALPHA = $2;
AC_DST_NO_PREMULT_ALPHA = $10;
AC_DST_NO_ALPHA = $20;

LWA_COLORKEY = $1;
LWA_ALPHA = $2;

ULW_COLORKEY = $1;
ULW_ALPHA =$2;
ULW_OPAQUE = $4;

type
TW2KTransForm = function (hwnd: HWND; crKey: TColor; bAlpha: byte;
dwFlags: DWORD): BOOL; stdcall;

procedure SetFormTransRate(Handle: HWND; Rate: Byte);
var
SetLayeredWindowAttributes: TW2KTransForm;
HModule: THandle;
begin
if(win32platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >=5) then
begin
SetWindownLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
HModule := LoadLibrary('user32.dll');
if HModule <> 0 then
begin
try
@SetLayeredWindowAttributes := GetProcAddress(HModule, 'SetLayeredWindowAttributes');
SetLayeredWindowAttributes(handle, $0, Rate, LWA_ALPHA);
except
end;
FreeLibrary(HModule);
end;
end;
end;
 
form1.Alphablend
form1.Alphablendvalue
这两个属性是D6才有的新属性
 
还是文不对题
我是问我的程序为什么可以运行 但是却不是半透明[:(!][:(!]
 
->而不是窗体半透明,我那个代码运行出来根本就没有窗体!!
你说的是不是桌面截图? 我用Fast库实现了从桌面淡出一个窗口的封面。
 
谁说没有form?
当然有form, 它的图片就是放在一个borderstyle=bsNone的form上, 如果光这点代码根本不可能在98下产生透明
一个wincontrol要在98下产生透明至少要满足下面几个条件:
1、window style必须包含WS_TRANSPARENT
2、它的parent的style 必须不能包括WS_CLIPCHILDREN属性
3、WM_ERASEBKGND消息里不做任何处理就返回1
根据以上2的条件, 只有childwindow才可能产生透明效果。form的parent是desktopwindow, 而在98下你根本没有可能更改desktopwindow的style
98下透明form的实现是这样的:
1、建立窗口前将整个桌面抓屏保存到内存, 在form的wm_erasebkgnd消息或wm_paint消息里将桌面图片的部分作为form的背景
2、如果窗口改变zorder/active/deactive之后, 当前form.visible := false; --->sleep足够长的一段时间以等待桌面重画完成--->重新抓屏--->form.visible := true;
3、因为form.visible := false後sleep的时间无法掌握, 所以只能尽量取最大值。 因此最后效果极差。 PIII机器如果没有很复杂的程序(如photoshop, IE, 甚至资源管理器等)运行的情况下一般 需要sleep 100-300ms。

 
呵呵
没想到引起这么多得争论
还有什么好方法吗?
我的好几个帖子没人回答,可以把分加到这里
 

Similar threads

后退
顶部