当移动/加载图像时,Delphi PNG图像显示矩形BUG

Naf*_*lem 6 delphi png image

在png图像周围,在加载图像上或移动图像时出现奇怪的矩形.

矩形在24位PNG或jpg中很少出现,但是32位PNG是个问题.有谁知道是什么原因造成的?PNG是在Photoshop中创建的.我也尝试了gimp但同样的问题.

24BitPNG-BetterResult

32BitPNG-BAD-BUG

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.
Run Code Online (Sandbox Code Playgroud)

我试过了.

...
protected
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;

...

begin

procedure TForm1.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  Message.Result := 1;
end;


end.
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 4

你的基本方法是有缺陷的。您不应该使用TImage控件来显示动画。这些控件设计用于显示静态图像。作为一个粗略的解决方案,您可以为表单启用双缓冲。通过设置DoubleBuffered为 来执行此操作True。这具有可能不希望的副作用。无论如何,整个方法应该让你感到恶心。

正确的方法是将整个图像渲染到绘图表面。在理想的情况下,您将拥有一个单一窗口控件,它响应 来渲染背景WM_ERASEBKGND,然后响应 来绘制动态内容WM_PAINT。这就是我要做的。

作为一个更简单的中途之家,您可以使用一个TPaintBox或什至表单的OnPaint处理程序。这些方法会让你根据 绘制整个图像WM_PAINT。那应该没有闪烁。如果没有,那么您可能需要诉诸于绘制离屏位图,然后将其传输到绘制表面。