トップへ(mam-mam.net/)

Rotate a TBitmap Image and Draw It on a Canvas (VCL & FMX) – Delphi Source Code Examples

Japanese

Rotate a TBitmap Image and Draw It on a Canvas (VCL & FMX) – Delphi Source Code Examples

In VCL, you can rotate and draw an image around any specified center point by using the coordinate transformation matrix (Direct2DCanvas matrix) of TCanvas.
In FMX, you can rotate and draw an image around any specified center point using the built‑in coordinate transformation matrix available in TCanvas.

Rotate an Image in VCL

Drag and drop two TImage components and two TButton components onto the form.

Rotate a TBitmap image and draw it on a Canvas (VCL, FMX)

Assign event handlers to TForm1.OnCreate, Button1.OnClick, and Button2.OnClick, then enter the source code shown below.
By using the DrawRotationBitmap method in the code, you can rotate and draw a TBitmap image using Direct2DCanvas.

procedure DrawRotationBitmap(
  SourceBitmap:TBitmap; DestCanvas:TCanvas; 
  Pt:TPoint; Rotation:Single; 
  W, H:Integer; Opacity:Byte=255);

SourceBitmap: TBitmap
The bitmap to be drawn.
DestCanvas: TCanvas
The destination canvas where the bitmap will be drawn.
Pt: TPoint
The drawing position and the center point of rotation. Point(X, Y)
(Example) Point(50, 100)
Rotation: Single
The rotation angle in degrees (clockwise is positive).
W, H: Integer
The width and height of the output image.
Opacity: Byte
Opacity value. 0 = transparent, 255 = fully opaque.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private }
  public
    { Public }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
uses Vcl.Direct2D, Winapi.D2D1;

// Draw SourceBitmap onto DestCanvas,
// rotated clockwise by Rotation degrees around Pt,
// with output size (W, H) and opacity (0–255).
procedure DrawRotationBitmap(SourceBitmap:TBitmap; DestCanvas:TCanvas;
  Pt:TPoint; Rotation:Single; W,H:Integer; Opacity:Byte=255);
var
  D2Canvas: TDirect2DCanvas;
  Pt2f: TD2DPoint2f;
  TranslationMatrix, RotationMatrix: TD2DMatrix3X2F;
begin
  Pt2f.x := Pt.X;
  Pt2f.y := Pt.Y;

  // Create a Direct2D canvas
  D2Canvas := TDirect2DCanvas.Create(
    DestCanvas, DestCanvas.ClipRect
  );

  // Begin drawing
  D2Canvas.BeginDraw;

  // Enable anti-aliasing
  D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);

  // Create a translation matrix that moves to Pt2f
  TranslationMatrix := TD2DMatrix3x2F.Translation(Pt2f);

  // Create a rotation matrix with center Pt2f and angle Rotation
  RotationMatrix := TD2DMatrix3x2F.Rotation(Rotation, Pt2f);

  // Combine translation and rotation matrices
  TranslationMatrix := TranslationMatrix * RotationMatrix;

  // Apply the transform to the Direct2D canvas
  D2Canvas.RenderTarget.SetTransform(TranslationMatrix);

  // Draw the SourceBitmap
  D2Canvas.StretchDraw(
    Rect(-W div 2, -H div 2, W div 2, H div 2),
    SourceBitmap,
    Opacity // opacity (0–255)
  );

  // Reset the transform
  D2Canvas.RenderTarget.SetTransform(TD2DMatrix3x2F.Identity);

  // End drawing
  D2Canvas.EndDraw;

  // Free the Direct2D canvas
  D2Canvas.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Rotate Image2.Bitmap by 20 degrees clockwise,
  // draw it at size (50,25) with opacity 100,
  // centered at (150,100) on Image1.Bitmap.Canvas.
  DrawRotationBitmap(
    Image2.Picture.Bitmap, Image1.Picture.Bitmap.Canvas,
    Point(150,100), 20, 50,25, 100
  );
  Image1.Refresh;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  // Rotate Image2.Bitmap by 20 degrees clockwise,
  // draw it at size (50,25) with opacity 100,
  // centered at (150,250) on Form1.Canvas.
  DrawRotationBitmap(
    Image2.Picture.Bitmap, Form1.Canvas,
    Point(150,250), 20, 50,25, 100
  );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Width := 300;
  Image1.Height := 200;
  Image1.Picture.Bitmap.SetSize(300,200);
  Image1.Picture.Bitmap.Canvas.Brush.Color := clWhite;
  Image1.Picture.Bitmap.Canvas.FillRect(Rect(0,0,300,200));
  Image1.Picture.Bitmap.Canvas.Pen.Color := clRed;
  Image1.Picture.Bitmap.Canvas.MoveTo(0,100);
  Image1.Picture.Bitmap.Canvas.LineTo(300,100);
  Image1.Picture.Bitmap.Canvas.MoveTo(150,0);
  Image1.Picture.Bitmap.Canvas.LineTo(150,200);

  Image2.Width := 100;
  Image2.Height := 50;
  Image2.Picture.Bitmap.SetSize(100,50);
  Image2.Picture.Bitmap.Canvas.Brush.Color := clBlue;
  Image2.Picture.Bitmap.Canvas.FillRect(Rect(0,0,100,50));
end;

end.

When you click "Button1", the image in "Image2" is rotated 20 degrees clockwise around the point (X=150, Y=100) on "Image1", then drawn at a size of 50×25 pixels with an opacity of 100/255.
When you click "Button2", the image in "Image2" is rotated 20 degrees clockwise around the point (X=150, Y=250) on "Form1", then drawn at a size of 50×25 pixels with an opacity of 100/255.

画像(TBitmap)を回転してCanvasに描画させる(VCL)

Rotate an Image in FMX

Drag and drop two TImage components and two TButton components onto the form.

Rotate a TBitmap image and draw it on a Canvas (FMX)

Assign event handlers to TForm1.OnCreate, Button1.OnClick, and Button2.OnClick, then enter the source code shown below.
By using the DrawRotationBitmap method in the code, you can rotate and draw a TBitmap image in FMX by applying a transformation matrix through TCanvas.SetMatrix.

procedure DrawRotationBitmap(
  SourceBitmap:TBitmap; DestCanvas:TCanvas;
  Pt:TPoint; Rotation:Single;
  W,H:Integer; Opacity:Single=1);
SourceBitmap: TBitmap
The bitmap to be drawn.
DestCanvas: TCanvas
The destination canvas where the bitmap will be rendered.
Pt: TPoint
The drawing position and the center point of rotation. Point(X, Y)
(Example) Point(50, 100)
Rotation: Single
The rotation angle in degrees (clockwise is positive).
W, H: Integer
The width and height of the output image.
Opacity: Single
Opacity value from 0.0 (transparent) to 1.0 (fully opaque).
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses System.Math.Vectors;

// Draw SourceBitmap onto DestCanvas,
// rotated clockwise by Rotation degrees around Pt,
// with output size (W, H) and opacity (0.0–1.0).
procedure DrawRotationBitmap(SourceBitmap:TBitmap; DestCanvas:TCanvas;
  Pt:TPointF; Rotation:Single; W,H:Integer; Opacity:Single=1);
var
  Matrix, TranslationMatrix, RotationMatrix: TMatrix;
begin
  DestCanvas.BeginScene();
  Matrix := DestCanvas.Matrix;

  // Create a translation matrix that moves to Pt
  TranslationMatrix :=
    System.Math.Vectors.TMatrix.CreateTranslation(
      Pt.X, Pt.Y
    );

  // Create a rotation matrix for Rotation degrees
  RotationMatrix :=
    System.Math.Vectors.TMatrix.CreateRotation(
      Rotation * Pi / 180
    );

  // Apply the combined rotation and translation matrix
  DestCanvas.SetMatrix(RotationMatrix * TranslationMatrix);

  DestCanvas.DrawBitmap(
    SourceBitmap,
    RectF(0,0,SourceBitmap.Width,SourceBitmap.Height),
    RectF(-W/2, -H/2, W/2, H/2),
    Opacity
  );

  // Restore the original matrix
  DestCanvas.SetMatrix(Matrix);

  DestCanvas.EndScene;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Rotate Image2.Bitmap by 20 degrees clockwise,
  // draw it at size (50,25) with opacity 0.7,
  // centered at (150,100) on Image1.Bitmap.Canvas.
  DrawRotationBitmap(
    Image2.Bitmap, Image1.Bitmap.Canvas,
    PointF(150,100), 20, 50,25, 0.7
  );
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  // Rotate Image2.Bitmap by 20 degrees clockwise,
  // draw it at size (50,25) with opacity 0.7,
  // centered at (150,250) on Form1.Canvas.
  DrawRotationBitmap(
    Image2.Bitmap, Form1.Canvas,
    PointF(150,250), 20, 50,25, 0.7
  );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Width := 300;
  Image1.Height := 200;
  Image1.Bitmap.SetSize(300,200);
  Image1.Bitmap.Canvas.BeginScene();
  Image1.Bitmap.Canvas.Fill.Color := TAlphaColorRec.White;
  Image1.Bitmap.Canvas.FillRect(RectF(0,0,300,200),0,0,[],1);
  Image1.Bitmap.Canvas.Stroke.Color := TAlphaColorRec.Red;
  Image1.Bitmap.Canvas.DrawLine(PointF(0,100), PointF(300,100), 1);
  Image1.Bitmap.Canvas.DrawLine(PointF(150,0), PointF(150,200), 1);
  Image1.Bitmap.Canvas.EndScene;

  Image2.Width := 100;
  Image2.Height := 50;
  Image2.Bitmap.SetSize(100,50);
  Image2.Bitmap.Canvas.BeginScene();
  Image2.Bitmap.Canvas.Fill.Color := TAlphaColorRec.Blue;
  Image2.Bitmap.Canvas.FillRect(RectF(0,0,100,50),0,0,[],1);
  Image2.Bitmap.Canvas.EndScene;
end;

end.

When you click "Button1", the image in "Image2" is rotated 20 degrees clockwise around the point (X=150, Y=100) on "Image1", then drawn at a size of 50×25 pixels with an opacity of 0.7.
When you click "Button2", the image in "Image2" is rotated 20 degrees clockwise around the point (X=150, Y=250) on "Form1", then drawn at a size of 50×25 pixels with an opacity of 0.7.

Rotate a TBitmap image and draw it on a Canvas (FMX)