Image Delphi GDIPLUS更改图像位置

Image Delphi GDIPLUS更改图像位置,image,delphi,gdi+,Image,Delphi,Gdi+,我试图实现一个简单的任务,但通过使用GDI+我找不到任何例子。 在我的代码中,我需要更改图像的位置(如果更具体的话,请参见顶部),但我不知道是否可以以更好的方式进行更改。 我现在就是这样做的: procedure TForm2.Timer1Timer(Sender: TObject); var I: Integer; begin if image1.Top = -93 then Begin for I := -93 to -1 do Begin Sleep(1

我试图实现一个简单的任务,但通过使用GDI+我找不到任何例子。 在我的代码中,我需要更改图像的位置(如果更具体的话,请参见顶部),但我不知道是否可以以更好的方式进行更改。 我现在就是这样做的:

procedure TForm2.Timer1Timer(Sender: TObject);
var
  I: Integer;
begin
  if image1.Top = -93 then
  Begin
    for I := -93 to -1 do
    Begin
    Sleep(10);
    image1.Top := Image1.Top + 1;
    Application.ProcessMessages;
  End;
End else if image1.Top = 0 then
Begin
  for I := 0 downto -92 do
  Begin
    Sleep(10);
    image1.Top := Image1.Top - 1;
    Application.ProcessMessages;
  End;
End;
end;
这很简单,但它不是平滑的,而是在每一步跳跃和重画

我感谢你的帮助

更新:
多亏了TLama和他的灵感,我发现Delphi2007的GDIPlus实现

移动控件是制作任何动画的错误方式,GDI+独立。相反,您应该记住要为动画更改的位置,在
OnTimer
事件中修改它,并告诉系统您要使目标控件无效。然后,在控件的
OnPaint
事件中,您应该按该位置渲染所需的任何内容

因此,首先,用
tpaitbox
替换
TImage
组件,因为
TImage
主要用于静态图像,而不是动态渲染。也使用两个计时器。一个用于向上动画,一个用于向下动画

下面的代码没有考虑计时器的近似值,它使用了不太为人所知的Delphi包装器:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Timer2: TTimer;
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  private
    GPImage: IGPImage;
    FImageTop: Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FImageTop := 0;
  Timer1.Interval := 15;
  Timer2.Interval := 15;
  DoubleBuffered := True;
  Timer1.Enabled := True;
  Timer2.Enabled := False;
  GPImage := TGPImage.Create('d:\Image.jpg');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // no need for the following line since it's a reference of the interface
  // GPImage := nil;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (FImageTop > -93) then
  begin
    FImageTop := FImageTop - 1;
    PaintBox1.Invalidate;
  end
  else
  begin
    Timer1.Enabled := False;
    Timer2.Enabled := True;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  if (FImageTop < 0) then
  begin
    FImageTop := FImageTop + 1;
    PaintBox1.Invalidate;
  end
  else
  begin
    Timer2.Enabled := False;
    Timer1.Enabled := True;
  end;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  GPGraphics: IGPGraphics;
begin
  GPGraphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);
  GPGraphics.DrawImage(GPImage, 0, FImageTop);
end;

end.
单元1;
接口
使用
窗口、消息、系统工具、变体、类、图形、控件、窗体、,
对话框、ExtCtrls、GdiPlus;
类型
TForm1=类(TForm)
定时器1:TTimer;
Timer2:TTimer;
PaintBox1:tPaintbox1;
过程表单创建(发送方:ToObject);
销毁程序表(发送方:TObject);
程序定时器1定时器(发送方:TObject);
程序定时器2定时器(发送方:ToObject);
程序喷漆箱1喷漆(发送方:TObject);
私有的
GPImage:IGPImage;
FImageTop:整数;
公众的
{公开声明}
结束;
变量
表1:TForm1;
实施
{$R*.dfm}
过程TForm1.FormCreate(发送方:TObject);
开始
FImageTop:=0;
计时器1.间隔:=15;
定时器2.间隔:=15;
双缓冲:=真;
Timer1.Enabled:=真;
Timer2.Enabled:=False;
GPImage:=TGPImage.Create('d:\Image.jpg');
结束;
程序TForm1.FormDestroy(发送方:ToObject);
开始
//不需要以下行,因为它是接口的引用
//GPImage:=nil;
结束;
程序TForm1.Timer1Timer(发送方:TObject);
开始
如果(FImageTop>-93),则
开始
FImageTop:=FImageTop-1;
油漆盒1.失效;
结束
其他的
开始
Timer1.Enabled:=False;
Timer2.Enabled:=真;
结束;
结束;
程序TForm1.Timer2Timer(发送方:TObject);
开始
如果(FImageTop<0),则
开始
FImageTop:=FImageTop+1;
油漆盒1.失效;
结束
其他的
开始
Timer2.Enabled:=False;
Timer1.Enabled:=真;
结束;
结束;
程序TForm1.PaintBox1Paint(发送方:TObject);
变量
图形:IGPGraphics;
开始
GPGraphics:=TGPGraphics.Create(PaintBox1.Canvas.Handle);
GPGraphics.DrawImage(GPImage,0,FImageTop);
结束;
结束。

移动控件是制作任何动画的错误方式,GDI+独立。相反,您应该记住要为动画更改的位置,在
OnTimer
事件中修改它,并告诉系统您要使目标控件无效。然后,在控件的
OnPaint
事件中,您应该按该位置渲染所需的任何内容

因此,首先,用
tpaitbox
替换
TImage
组件,因为
TImage
主要用于静态图像,而不是动态渲染。也使用两个计时器。一个用于向上动画,一个用于向下动画

下面的代码没有考虑计时器的近似值,它使用了不太为人所知的Delphi包装器:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Timer2: TTimer;
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  private
    GPImage: IGPImage;
    FImageTop: Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FImageTop := 0;
  Timer1.Interval := 15;
  Timer2.Interval := 15;
  DoubleBuffered := True;
  Timer1.Enabled := True;
  Timer2.Enabled := False;
  GPImage := TGPImage.Create('d:\Image.jpg');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // no need for the following line since it's a reference of the interface
  // GPImage := nil;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (FImageTop > -93) then
  begin
    FImageTop := FImageTop - 1;
    PaintBox1.Invalidate;
  end
  else
  begin
    Timer1.Enabled := False;
    Timer2.Enabled := True;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  if (FImageTop < 0) then
  begin
    FImageTop := FImageTop + 1;
    PaintBox1.Invalidate;
  end
  else
  begin
    Timer2.Enabled := False;
    Timer1.Enabled := True;
  end;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  GPGraphics: IGPGraphics;
begin
  GPGraphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);
  GPGraphics.DrawImage(GPImage, 0, FImageTop);
end;

end.
单元1;
接口
使用
窗口、消息、系统工具、变体、类、图形、控件、窗体、,
对话框、ExtCtrls、GdiPlus;
类型
TForm1=类(TForm)
定时器1:TTimer;
Timer2:TTimer;
PaintBox1:tPaintbox1;
过程表单创建(发送方:ToObject);
销毁程序表(发送方:TObject);
程序定时器1定时器(发送方:TObject);
程序定时器2定时器(发送方:ToObject);
程序喷漆箱1喷漆(发送方:TObject);
私有的
GPImage:IGPImage;
FImageTop:整数;
公众的
{公开声明}
结束;
变量
表1:TForm1;
实施
{$R*.dfm}
过程TForm1.FormCreate(发送方:TObject);
开始
FImageTop:=0;
计时器1.间隔:=15;
定时器2.间隔:=15;
双缓冲:=真;
Timer1.Enabled:=真;
Timer2.Enabled:=False;
GPImage:=TGPImage.Create('d:\Image.jpg');
结束;
程序TForm1.FormDestroy(发送方:ToObject);
开始
//不需要以下行,因为它是接口的引用
//GPImage:=nil;
结束;
程序TForm1.Timer1Timer(发送方:TObject);
开始
如果(FImageTop>-93),则
开始
FImageTop:=FImageTop-1;
油漆盒1.失效;
结束
其他的
开始
Timer1.Enabled:=False;
Timer2.Enabled:=真;
结束;
结束;
程序TForm1.Timer2Timer(发送方:TObject);
开始
如果(FImageTop<0),则
开始
FImageTop:=FImageTop+1;
油漆盒1.失效;
结束
其他的
开始
Timer2.Enabled:=False;
Timer1.Enabled:=真;
结束;
结束;
程序TForm1.PaintBox1Paint(发送方:TObject);
变量
图形:IGPGraphics;
开始
GPGraphics:=TGPGraphics.Create(PaintBox1.Canvas.Handle);
GPGraphics.DrawImage(GPImage,0,FImageTop);
结束;
结束。

您可能需要研究双缓冲动画。@沃伦,移动控件是一种错误的动画制作方法!您应该记住要绘制的内容的位置,在
OnTimer
事件中修改它,并告诉系统您要使控件无效。当然可以。不过,双缓冲动画技术加上在画布上绘图,效果很好。您可能想研究双缓冲动画。@Warren,移动控件是制作任何动画的错误方法!你应该记住你想画的东西的位置,在
OnTimer中修改它