【发布时间】:2014-04-15 02:45:00
【问题描述】:
在加载图像或移动图像时,png图像周围出现奇怪的矩形。
矩形在 24 位 PNG 或 jpg 中很少出现,但在 32 位 PNG 中出现问题。有谁知道是什么原因造成的? PNG是在Photoshop中创建的。我也试过 gimp 但同样的问题。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, pngimage, jpeg, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Image2: TImage;
Timer1: TTimer;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Label1: TLabel;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
png:TPngImage;
rs:TResourceStream;
ms:TMemoryStream;
implementation
{$R *.dfm}
{$R FB.RES}
procedure TForm1.Button1Click(Sender: TObject);
begin
rs:=TResourceStream.Create(hInstance,'24bitpng',RT_RCDATA);
png:=TPngImage.Create;
png.LoadFromStream(rs);
Image1.Picture.Graphic:=png;
rs.Free;
Label1.Caption:=Button1.Caption;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
rs:=TResourceStream.Create(hInstance,'32bitpng',RT_RCDATA);
png:=TPngImage.Create;
png.LoadFromStream(rs);
Image1.Picture.Graphic:=png;
rs.Free;
Label1.Caption:=Button2.Caption;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Form1.Close;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Timer1.Enabled:=True;
Image2.Left:=0;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DoubleBuffered:=True; //This did the job, now no flickering around
Form1.BorderStyle:=bsnone;
Form1.Position:=poScreenCenter;
Label1.Caption:=Button1.Caption;
end;
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Screen.Cursor:=crSizeAll;
ReleaseCapture;
SendMessage(Form1.Handle, WM_SYSCOMMAND, 61458, 0) ;
Screen.Cursor:=crDefault;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if image2.Left<300 then
image2.Left:=image2.Left+2
else
Timer1.Enabled:=False;
end;
end.
这个我试过了。
...
protected
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
...
begin
procedure TForm1.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
Message.Result := 1;
end;
end.
【问题讨论】:
-
您只是应该不通过移动 VCL 控件来制作动画!相反,在
OnPaint中使用 GDI 手动绘制。 Examples -
这里是源代码+编译后的二进制文件copy.com/s/FSczlwV4C0X0NEi6/FootBall-PNG.rar
-
在表单上设置 DoubleBuffered。或者实现你自己的离屏处理。
-
安德烈亚斯是正确的。响应
WM_ERASEBKGND渲染背景,响应WM_PAINT渲染前景。 -
@David - 双缓冲,或者一般来说,离屏图像渲染没有错。尽管有时可能并不理想,但我认为这不是一种情况。毕竟,您不应该在终端会话中进行开球。