GDI +を使用して回転イメージの中心を合わせるにはどうすればよいですか?GDI +を使用して回転イメージを中心にする
ここで私の問題を示す小さな例を作成しました。
GUI OpenPictureDialog、クライアントに整列ペイントボックスと
ブランクフォーム。 DoubleClickイベントとOnPaintEventをPaintBoxに追加します。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Vcl.ExtCtrls, Vcl.ExtDlgs, GDIPAPI, GDIPOBJ, GDIPUTIL;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
OpenPictureDialog1: TOpenPictureDialog;
procedure PaintBox1Paint(Sender: TObject);
procedure PaintBox1DblClick(Sender: TObject);
private
{ Private declarations }
FImage: TGPImage;
procedure DrawImage(aMaxWidth, aMaxHeight: Cardinal); overload;
procedure DrawImage; overload;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DrawImage(aMaxWidth, aMaxHeight: Cardinal);
var
Ratio: Double;
Height, Width, HeightOffset, WidthOffset: Cardinal;
begin
PaintBox1.Canvas.Brush.Color := clWhite;
FillRect(PaintBox1.Canvas.Handle, Rect(0, 0, aMaxWidth, aMaxHeight), PaintBox1.Canvas.Brush.Handle);
if FImage = nil then
exit;
Ratio := FImage.GetWidth/FImage.GetHeight;
Height := FImage.GetHeight;
Width := FImage.GetWidth;
if (FImage.GetHeight <= aMaxHeight) and (FImage.GetWidth <= aMaxWidth) then
{ do nothing }; // Width and height allready set
if (FImage.GetHeight <= aMaxHeight) and (FImage.GetWidth > aMaxWidth) then
Width := Round(FImage.GetHeight * Ratio);
if (FImage.GetHeight > aMaxHeight) and (FImage.GetWidth > aMaxWidth) then
if Ratio > 1 then
begin
Height := Round(aMaxWidth/Ratio);
Width := aMaxWidth;
end
else
begin
Width := Round(aMaxHeight * Ratio);
Height := aMaxHeight;
end;
HeightOffset := (aMaxHeight - Height) div 2;
WidthOffset := (aMaxWidth - Width) div 2;
with TGPGraphics.Create(PaintBox1.Canvas.Handle) do
try
// RotateTransform(30);
DrawImage(FImage, WidthOffset, HeightOffset, Width, Height);
finally
Free;
end;
end;
procedure TForm1.DrawImage;
begin
DrawImage(PaintBox1.Width, PaintBox1.Height);
end;
procedure TForm1.PaintBox1DblClick(Sender: TObject);
begin
if not OpenPictureDialog1.Execute then
exit;
FImage.Free;
FImage := TGPImage.Create(OpenPictureDialog1.FileName);
DrawImage;
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
DrawImage;
end;
end.
背後
コード私は私のイメージ何もかもが回転しない場合は罰金workesが、私はRotateTransform(30);
を呼び出すときに画像が中心から外れています。
私は、原点を移動しようとしています
with TGPGraphics.Create(PaintBox1.Canvas.Handle) do
try
TranslateTransform(WidthOffset + (Width div 2), HeightOffset + (Height div 2));
RotateTransform(30);
DrawImage(FImage, WidthOffset, HeightOffset, Width, Height);
finally
Free;
end;
しかし、その後の画像は表示されません。
結果、私はこれで終わったの下にMBOの答えを使用して
:問題の
がprocedure TForm1.DrawImage(aMaxWidth, aMaxHeight: Cardinal; aRotationAngle: Double);
var
radAngle, Ratio: Double;
Height, Width: Cardinal;
Wanted_CX, Wanted_CY: Integer;
WCX_InRotated, WCY_InRotated, xr, yr: Single;
begin
PaintBox1.Canvas.Brush.Color := clWhite;
FillRect(PaintBox1.Canvas.Handle, Rect(0, 0, aMaxWidth, aMaxHeight), PaintBox1.Canvas.Brush.Handle);
if FImage = nil then
exit;
Ratio := FImage.GetWidth/FImage.GetHeight;
Height := FImage.GetHeight;
Width := FImage.GetWidth;
if (FImage.GetHeight <= aMaxHeight) and (FImage.GetWidth <= aMaxWidth) then
{ do nothing }; // Width and height allready set
if (FImage.GetHeight <= aMaxHeight) and (FImage.GetWidth > aMaxWidth) then
Width := Round(FImage.GetHeight * Ratio);
if (FImage.GetHeight > aMaxHeight) and (FImage.GetWidth > aMaxWidth) then
if Ratio > 1 then
begin
Height := Round(aMaxWidth/Ratio);
Width := aMaxWidth;
end
else
begin
Width := Round(aMaxHeight * Ratio);
Height := aMaxHeight;
end;
radAngle := DegToRad(aRotationAngle);
Wanted_CX := PaintBox1.Width div 2;
Wanted_CY := PaintBox1.Height div 2;
xr := 0.5 * (Width * Cos(radAngle) - Height * Sin(radAngle)); // shift of rotated center
yr := 0.5 * (Width * Sin(radAngle) + Height * Cos(radAngle)); // relative to left top corner
with TGPGraphics.Create(PaintBox1.Canvas.Handle) do
try
RotateTransform(aRotationAngle);
WCX_InRotated := Cos(radAngle) * (Wanted_CX - xr) + Sin(radAngle) * (Wanted_CY - yr);
WCY_InRotated := -Sin(radAngle) * (Wanted_CX - xr) + Cos(radAngle) * (Wanted_CY - yr);
DrawImage(FImage, WCX_InRotated, WCY_InRotated);
finally
Free;
end;
end;
@NGLNを求め、この質問(+回転のためのいくつかの他の技術を)答えは[こちら](http://stackoverflow.com/q/10633400/2292722) –