Ave*_*oes 2 delphi image-processing rotation
我只是为了一个有趣的虚拟桌面与朋友一起玩Magic The Gathering.我正在使用Delphi 2010.这些卡在应用程序中由TImage
组件表示(加载从数据库加载的卡的PNG文件).这里的要点是,在MTG中,一个非常常见的事情是点击一张卡片(向右旋转90度).有一个简单的方法可以做到这一点?我真的不需要"动画",只需点击一次旋转的卡片(虽然动画会很好).游戏应该与许多卡同时工作,它们可以移动到表单中的任何位置.我正在考虑在数据库中轻拍和未打开卡片的图像,但如果有一种漂亮而有效的方式来旋转卡片,这可能是一种过度杀伤力.
有任何想法吗?
或者你可以离开TImage
并使用eg TPaintBox
和GDI +库.GDI + RotateFlip
直接用这个方法.使用GDI+ Library for Delphi
它看起来像:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ActiveX, GDIPOBJ, GDIPAPI;
type
TForm1 = class(TForm)
Button1: TButton;
PaintBox1: TPaintBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
private
FImage: TGPImage;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
Stream: IStream;
BlobStream: TMemoryStream;
begin
BlobStream := TMemoryStream.Create;
try
// assuming the BlobStream here has a valid image loaded from a database
Stream := TStreamAdapter.Create(BlobStream);
FImage := TGPImage.Create(Stream);
finally
BlobStream.Free;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FImage.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FImage.RotateFlip(Rotate90FlipNone);
PaintBox1.Invalidate;
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
with TGPGraphics.Create(PaintBox1.Canvas.Handle) do
try
DrawImage(FImage, 0, 0);
finally
Free;
end;
end;
end.
Run Code Online (Sandbox Code Playgroud)
这样的矫枉过正,不是吗? - ?
您可以使用TPaintBox而不是TImage,并使用带旋转矩阵的SetWorldTransform来绘制抽头卡.我使用StretchDrawRotated:
procedure XForm_SetRotation(out AXForm: TXForm; AAngle: Extended; ACenter: TPoint);
var
SinA, CosA: Extended;
begin
SinCos(AAngle, SinA, CosA);
AXForm.eM11 := CosA;
AXForm.eM12 := SinA;
AXForm.eM21 := -SinA;
AXForm.eM22 := CosA;
AXForm.eDx := (ACenter.X - (CosA * ACenter.X)) + ((SinA * ACenter.Y));
AXForm.eDy := (ACenter.Y - (SinA * ACenter.X)) - ((CosA * ACenter.Y));
end;
procedure StretchDrawRotated(ACanvas: TCanvas; const ARect: TRect; AAngle: Extended; ACenter: TPoint; AGraphic: TGraphic);
var
XForm, XFormOld: TXForm;
GMode: Integer;
begin
GMode := SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
try
if GetWorldTransform(ACanvas.Handle, XFormOld) then
try
XForm_SetRotation(XForm, AAngle, ACenter);
SetWorldTransform(ACanvas.Handle, XForm);
ACanvas.StretchDraw(ARect, AGraphic);
finally
SetWorldTransform(ACanvas.Handle, XFormOld);
end;
finally
SetGraphicsMode(ACanvas.Handle, GMode);
end;
end;
Run Code Online (Sandbox Code Playgroud)
这种做法的老方法是使用PlgBlt.
procedure RotateBitmap90CW(b1,b2:TBitmap);
var
x,y:integer;
p:array[0..2] of TPoint;
begin
x:=b1.Width;
y:=b1.Height;
b2.Width:=y;
b2.Height:=x;
p[0].X:=y;
p[0].Y:=0;
p[1].X:=y;
p[1].Y:=x;
p[2].X:=0;
p[2].Y:=0;
PlgBlt(b2.Canvas.Handle,p,b1.Canvas.Handle,0,0,x,y,0,0,0);
end;
Run Code Online (Sandbox Code Playgroud)