Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image Delphi PNG图像在移动/加载图像时显示矩形错误_Image_Delphi_Png - Fatal编程技术网

Image Delphi PNG图像在移动/加载图像时显示矩形错误

Image Delphi PNG图像在移动/加载图像时显示矩形错误,image,delphi,png,Image,Delphi,Png,加载图像或移动图像时,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, StdC

加载图像或移动图像时,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.


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

正确的方法是将整个图像渲染到图形表面。在理想情况下,您可以使用一个窗口控件,该控件根据
WM_ERASEBKGND
渲染背景,然后根据
WM_PAINT
绘制动态内容。这就是我要做的


作为一个简单的中途之家,您可以使用
tpaitbox
或者甚至表单的
OnPaint
处理程序。这些方法将使您绘制整个图像以响应
WM\u PAINT
。应该没有闪烁。如果没有,那么您可能需要求助于对屏幕外位图进行绘制,然后将其分片到绘制表面

您根本不应该通过移动VCL控件来制作动画!相反,在
OnPaint
中使用GDI手动绘制。这里是源代码+编译的二进制集合,在表单上进行双缓冲。或者实现自己的屏幕外处理。Andreas是正确的。渲染背景以响应
WM_ERASEBKGND
,渲染前景以响应
WM_PAINT
@David-双缓冲,或者通常,屏幕外图像渲染是正确的。虽然有时这可能不可取,但我不认为这是一种情况。毕竟,你不应该在终端会话中玩开球。我先尝试了WM_ERASEBKGND,但它周围有一个黑色背景,我需要自定义形状表单,然后我设置DoubleBuffered:=True;现在没有闪烁around@Nafelem您没有正确实现WM_ERASEBKGND的处理程序。你因为错误的原因拒绝了这种方法。另一方面,除非你有Win32方面的经验,否则你很难做到这一点。双缓冲很好,因为你可以忍受有点不舒服。我尝试为WM_橡皮擦BKGND(上面编辑的代码)实现一个处理程序。你要渲染背景以响应
WM_橡皮擦BKGND
。这就是我在回答中所说的。我不确定你是否真正理解我的观点。这个想法是答案的第二部分,从“正确的方法”开始,就是你扔掉你现在拥有的东西。去掉两个
TImage
控件。并直接在窗口控件上绘制。
...
protected
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;

...

begin

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


end.