【问题标题】:Delphi GDIPLUS change image positionDelphi GDIPLUS 改变图像位置
【发布时间】:2013-03-24 01:52:46
【问题描述】:

我试图通过使用 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 和他的启发,我找到了 this GDIPlus 为 delphi 2007 实现

【问题讨论】:

  • 你可能想看看双缓冲动画。
  • @Warren,移动控件是一种错误的动画方式!您应该记住要绘制的位置,在OnTimer事件中修改它并告诉系统您要使控件无效。
  • 当然可以。然而,双缓冲动画技术加上在画布上绘图,效果很好。

标签: image delphi gdi+


【解决方案1】:

移动控制是一种错误的动画方式,与 GDI+ 无关。相反,您应该记住要为动画更改的位置,在OnTimer 事件中修改它并告诉系统您要使目标控件无效。然后在控件的OnPaint 事件中,您应该在该位置呈现您想要的任何内容。

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

以下代码没有考虑计时器的近似值,它使用了鲜为人知的 Delphi 2009 GDI+ Library 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 但我不会使用 2 个计时器 .... FImageTop := FImageTop + FStepDistance;如果 (FImageTop > 99) 或 (FImageTop
  • 感谢 TLama,这正是我想要的!
  • 啊,虽然问题已经回答了,但我想问一下如果我想用PNG代替JPG怎么办?
  • 这就是 GDI+ 的美妙之处。它有一个用于 BMP、GIF、JPEG、PNG、TIFF 和 EMF 文件解码器的built in support。因此,只需加载该文件即可完成!
  • 我刚拿到我的电脑,对测试感到非常兴奋,但后来我意识到我有 D2007 并且没有 GDIplus,所以试图找到一种解决方法...... :(
猜你喜欢
  • 2016-08-12
  • 2023-03-23
  • 2021-11-10
  • 2011-08-10
  • 2018-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
相关资源
最近更新 更多