Delphi Programming / Object Pascal
[掲載 2012年12月14日] [更新 2012年12月14日] GDI+ 関係サンプル
GDI+ 関係サンプル
G100_TGPMatrix による座標変換
動作確認等
Windows 7 U64(SP1) + Delphi XE(UP1) Pro
G100_GDIPlus_TGPMatrix.zip [3,705 KB] 2012年12月14日版 (EXE 同梱)
TGPMatrix クラスは,3 行 3 列のマトリックス (行列) を扱うクラスです.座標値に対して次のような演算を実行します.1 列目は X 座標値に対する,2 列目は Y 座標値に対する変換で,3 列目はダミーの列です.
第 3 行目を追加することにより,座標値の線形変換と平行移動を組み合わせたアフィン変換を可能にしています.そのために第 3 例目が追加されています.
例えば,RotateAt 関数は,回転中心座標を指定しての回転ができますが,内部では次のような演算を実行していることになります.ここで,θは回転角度で,Xc, Yc が回転の中心座標値です.
TGPMatrix では,複数の行列に対して同時に演算させることもできますが,注意が必要です.線形代数を学習された方にとっては,既知のことですが,行列 A, B があった場合,A * B と B * A の結果は特別な行例でない限り違います.
このページのサンプルは,行列の要素ごとのサンプルとなっていますが,実際にはこれらを組み合わせて使用することになるでしょう.
行列の要素の代入は,SetElements 関数で行います.行列の要素は,3 X 3 ですが,1 列目と 2 列目だけを代入します.1, 2, 3 行目の順にセットします.
次の行列の演算をして,描画位置の座標を移動するサンプルです.
図1
設計時画面
図2
実行開始画面
図3
X 軸方向への移動例
図4
Y 軸方向への移動例
図5
X 軸と Y 軸方向の移動例
copy code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, GDIPAPI, GDIPOBJ, ComCtrls;
type
TMyPanel = class (TPanel)
private
FXValue : Single;
FYValue : Single;
procedure SetXValue(const Value: Single);
procedure SetYValue(const Value: Single);
protected
procedure Paint; override ;
public
constructor Create(AOwner: TComponent); override ;
property XValue : Single read FXValue write SetXValue;
property YValue : Single read FYValue write SetYValue;
end ;
TForm1 = class (TForm)
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
private
{ Private 宣言 }
MyPanel : TMyPanel;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// =============================================================================
// フォーム生成時の処理
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := 'GDI+ TGPMatrix 平行移動' ;
// 描画するコントロールを生成
MyPanel := TMyPanel.Create(Self);
with MyPanel do begin
Parent := Self;
SetBounds(5 , 70 , Self.ClientWidth - 10 , Self.ClientHeight - 75 );
DoubleBuffered := True;
ControlStyle := MyPanel.ControlStyle + [csOpaque];
BevelOuter := bvNone;
Visible := True;
Color := clWhite;
ParentBackground := False;
Anchors := [akLeft, akTop, akRight, akBottom];
end ;
// 水平方向への移動量
with TrackBar1 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -200 ;
Max := 200 ;
Position := 0 ;
end ;
// 垂直方向への移動量
with TrackBar2 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -200 ;
Max := 200 ;
Position := 0 ;
end ;
end ;
// =============================================================================
// TrackBar1のOnClickイベント処理
// X軸方向の移動量
// =============================================================================
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.XValue := TrackBar1.Position;
end ;
// =============================================================================
// TrackBar2のOnClickイベント処理
// Y軸方向の移動量
// =============================================================================
procedure TForm1.TrackBar2Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.YValue := TrackBar2.Position;
end ;
{ TMyPanel }
// -----------------------------------------------------------------------------
// コンストラクタ
// 各種プロパティの初期化
// -----------------------------------------------------------------------------
constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited ;
FXValue := 0.0 ;
FYValue := 0.0 ;
end ;
// -----------------------------------------------------------------------------
// XValueプロパティ設定用メソッド
// X軸方向の移動量
// -----------------------------------------------------------------------------
procedure TMyPanel.SetXValue(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FXValue <> Value then begin
FXValue := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// YValueプロパティ設定用メソッド
// Y軸方向の移動量
// -----------------------------------------------------------------------------
procedure TMyPanel.SetYValue(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FYValue <> Value then begin
FYValue := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// TMyPanelクラスのPaintメソッド
// 実際の描画コード
// -----------------------------------------------------------------------------
procedure TMyPanel.Paint;
var
LObjWidth : Integer;
LObjHeight : Integer;
LObjRect : TGPRect;
LXLocation : Integer;
LYLocation : Integer;
LGPGraphic : TGPGraphics;
LGPBrush : TGPHatchBrush;
LGPFontFamily : TGPFontFamily;
LGPStrFormat : TGPStringFormat;
LGPPath : TGPGraphicsPath;
LGPMatrix : TGPMatrix;
LGPPen : TGPPen;
LColor : Cardinal;
begin
inherited ;
// 描画する四角形と楕円の領域とサイズ
LObjWidth := 130 ;
LObjHeight := 100 ;
LObjRect := MakeRect(0 , 0 , LObjWidth, LObjHeight);
// 座標原点位置の値
LXLocation := Width div 2 ;
LYLocation := Height div 2 ;
// このTMyPanelのCanvasを描画先にしてTGPGraphicsのインスタンスを生成
LGPGraphic := TGPGraphics.Create(Canvas.Handle);
// 座標の原点を (FXLocation, FYLocation) に移動する
LGPGraphic.TranslateTransform(LXLocation, LYLocation);
// ブラシを生成
LColor := ColorRefToARGB($804000 );
LGPPen := TGPPen.Create(LColor, 1 );
LGPBrush := TGPHatchBrush.Create(HatchStyle30Percent, aclWhite, LColor);
// 文字列の書式等を設定
LGPFontFamily := TGPFontFamily.Create('Arial Black' );
LGPStrFormat := TGPStringFormat.Create;
LGPStrFormat.SetAlignment(StringAlignmentCenter);
LGPStrFormat.SetLineAlignment(StringAlignmentCenter);
// パスを生成して四角形と楕円と文字列を追加
LGPPath := TGPGraphicsPath.Create;
LGPPath.AddRectangle(LObjRect);
LGPPath.AddEllipse(LObjRect);
LGPPath.AddString('DELPHI' ,
-1 ,
LGPFontFamily,
FontStyleRegular,
25 ,
LObjRect,
LGPStrFormat);
// TGPMatrixを生成して要素を代入
LGPMatrix := TGPMatrix.Create;
LGPMatrix.SetElements(1.0 , 0.0 ,
0.0 , 1.0 ,
FXValue, FYValue);
// マトリックスの情報をパスに渡して,パスを描画
LGPPath.Transform(LGPMatrix);
LGPGraphic.FillPath(LGPBrush, LGPPath);
LGPGraphic.DrawPath(LGPPen, LGPPath);
// 座標原点を交差する座標軸を描く
LGPPen.SetColor(aclBlack);
LGPPen.SetWidth(1.0 );
LGPPen.SetDashStyle(DashStyleDash);
LGPGraphic.DrawLine(LGPPen, 0 , -LYLocation, 0 , LYLocation);
LGPGraphic.DrawLine(LGPPen, -LXLocation, 0 , LXLocation, 0 );
// Createしたオブジェクトは解放する
LGPGraphic.Free;
LGPBrush.Free;
LGPFontFamily.Free;
LGPStrFormat.Free;
LGPPath.Free;
LGPMatrix.Free;
LGPPen.Free;
end ;
end .
次のマトリックスを使用して,X 軸方向と Y 軸方向の倍率を変更するサンプルです.
図6
設計時画面
図7
実行開始画面
図8
実行結果例
copy code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, GDIPAPI, GDIPOBJ, ComCtrls;
type
TMyPanel = class (TPanel)
private
FXScale : Single;
FYScale : Single;
procedure SetXScale(const Value: Single);
procedure SetYScale(const Value: Single);
protected
procedure Paint; override ;
public
constructor Create(AOwner: TComponent); override ;
property XScale : Single read FXScale write SetXScale;
property YScale : Single read FYScale write SetYScale;
end ;
TForm1 = class (TForm)
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
private
{ Private 宣言 }
MyPanel : TMyPanel;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// =============================================================================
// フォーム生成時の処理
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := 'GDI+ TGPMatrix X 軸と Y 軸方向の倍率' ;
// 描画するコントロールを生成
MyPanel := TMyPanel.Create(Self);
with MyPanel do begin
Parent := Self;
SetBounds(5 , 70 , Self.ClientWidth - 10 , Self.ClientHeight - 75 );
DoubleBuffered := True;
ControlStyle := MyPanel.ControlStyle + [csOpaque];
BevelOuter := bvNone;
Visible := True;
Color := clWhite;
ParentBackground := False;
Anchors := [akLeft, akTop, akRight, akBottom];
end ;
// X軸方向の倍率設定用
// -3.0~3.0とするために100倍の値としている
with TrackBar1 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -300 ;
Max := 300 ;
Position := 100 ;
end ;
// Y軸方向の倍率設定用
// -3.0~3.0とするために100倍の値としている
with TrackBar2 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -300 ;
Max := 300 ;
Position := 100 ;
end ;
end ;
// =============================================================================
// TrackBar1のOnClickイベント処理
// X軸方向の倍率の設定
// =============================================================================
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.XScale := TrackBar1.Position / 100.0 ;
end ;
// =============================================================================
// TrackBar2のOnClickイベント処理
// Y軸方向の倍率の設定
// =============================================================================
procedure TForm1.TrackBar2Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.YScale := TrackBar2.Position / 100.0 ;
end ;
{ TMyPanel }
// -----------------------------------------------------------------------------
// コンストラクタ
// 各種プロパティの初期化
// -----------------------------------------------------------------------------
constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited ;
FXScale := 0.0 ;
FYScale := 0.0 ;
end ;
// -----------------------------------------------------------------------------
// XScaleプロパティ設定用メソッド
// X軸方向の倍率の設定
// -----------------------------------------------------------------------------
procedure TMyPanel.SetXScale(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FXScale <> Value then begin
FXScale := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// YScaleプロパティ設定用メソッド
// Y軸方向の倍率の設定
// -----------------------------------------------------------------------------
procedure TMyPanel.SetYScale(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FYScale <> Value then begin
FYScale := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// TMyPanelクラスのPaintメソッド
// 実際の描画コード
// -----------------------------------------------------------------------------
procedure TMyPanel.Paint;
var
LObjWidth : Integer;
LObjHeight : Integer;
LObjRect : TGPRect;
LXLocation : Integer;
LYLocation : Integer;
LGPGraphic : TGPGraphics;
LGPBrush : TGPHatchBrush;
LGPFontFamily : TGPFontFamily;
LGPStrFormat : TGPStringFormat;
LGPPath : TGPGraphicsPath;
LGPMatrix : TGPMatrix;
LGPPen : TGPPen;
LColor : Cardinal;
begin
inherited ;
// 描画する四角形と楕円の領域とサイズ
LObjWidth := 130 ;
LObjHeight := 100 ;
LObjRect := MakeRect(0 , 0 , LObjWidth, LObjHeight);
// 座標原点位置の値
LXLocation := Width div 2 ;
LYLocation := Height div 2 ;
// このTMyPanelのCanvasを描画先にしてTGPGraphicsのインスタンスを生成
LGPGraphic := TGPGraphics.Create(Canvas.Handle);
// 座標の原点を (FXLocation, FYLocation) に移動する
LGPGraphic.TranslateTransform(LXLocation, LYLocation);
// ブラシを生成
LColor := ColorRefToARGB($804000 );
LGPPen := TGPPen.Create(LColor, 1 );
LGPBrush := TGPHatchBrush.Create(HatchStyle30Percent, aclWhite, LColor);
// 文字列の書式等を設定
LGPFontFamily := TGPFontFamily.Create('Arial Black' );
LGPStrFormat := TGPStringFormat.Create;
LGPStrFormat.SetAlignment(StringAlignmentCenter);
LGPStrFormat.SetLineAlignment(StringAlignmentCenter);
// パスを生成して四角形と楕円と文字列を追加
LGPPath := TGPGraphicsPath.Create;
LGPPath.AddRectangle(LObjRect);
LGPPath.AddEllipse(LObjRect);
LGPPath.AddString('DELPHI' ,
-1 ,
LGPFontFamily,
FontStyleRegular,
25 ,
LObjRect,
LGPStrFormat);
// TGPMatrixを生成して要素を代入
LGPMatrix := TGPMatrix.Create;
LGPMatrix.SetElements(FXScale, 0.0 ,
0.0 , FYScale,
0.0 , 0.0 );
// マトリックスの情報をパスに渡して,パスを描画
LGPPath.Transform(LGPMatrix);
LGPGraphic.FillPath(LGPBrush, LGPPath);
LGPGraphic.DrawPath(LGPPen, LGPPath);
// 座標原点を交差する座標軸を描く
LGPPen.SetColor(aclBlack);
LGPPen.SetWidth(1.0 );
LGPPen.SetDashStyle(DashStyleDash);
LGPGraphic.DrawLine(LGPPen, 0 , -LYLocation, 0 , LYLocation);
LGPGraphic.DrawLine(LGPPen, -LXLocation, 0 , LXLocation, 0 );
// Createしたオブジェクトは解放する
LGPGraphic.Free;
LGPBrush.Free;
LGPFontFamily.Free;
LGPStrFormat.Free;
LGPPath.Free;
LGPMatrix.Free;
LGPPen.Free;
end ;
end .
03_ TGPMatrix による平行四辺形の描画領域
行列の次の要素を変えると,描画領域が平行四辺形となります.対象のオブジェクトが画像であれば,傾斜した画像 (傾斜イメージ) ということになります.
図9
設計時画面
図10
実行開始画面
図11
実行結果例
リスト3
TGPMatrix による平行四辺形の描画領域
copy code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, GDIPAPI, GDIPOBJ, ComCtrls;
type
TMyPanel = class (TPanel)
private
FXAddValue : Single;
FYAddValue : Single;
procedure SetXAddValue(const Value: Single);
procedure SetYAddValue(const Value: Single);
protected
procedure Paint; override ;
public
constructor Create(AOwner: TComponent); override ;
property XAddValue : Single read FXAddValue write SetXAddValue;
property YAddValue : Single read FYAddValue write SetYAddValue;
end ;
TForm1 = class (TForm)
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
private
{ Private 宣言 }
MyPanel : TMyPanel;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// =============================================================================
// フォーム生成時の処理
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := 'GDI+ TGPMatrix 平行四辺形の描画領域' ;
// 描画するコントロールを生成
MyPanel := TMyPanel.Create(Self);
with MyPanel do begin
Parent := Self;
SetBounds(5 , 70 , Self.ClientWidth - 10 , Self.ClientHeight - 75 );
DoubleBuffered := True;
ControlStyle := MyPanel.ControlStyle + [csOpaque];
BevelOuter := bvNone;
Visible := True;
Color := clWhite;
ParentBackground := False;
Anchors := [akLeft, akTop, akRight, akBottom];
end ;
// X軸方向の値に加算する値の設定
with TrackBar1 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -300 ;
Max := 300 ;
Position := 0 ;
end ;
// Y軸方向の値に加算する値の設定
with TrackBar2 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -300 ;
Max := 300 ;
Position := 0 ;
end ;
end ;
// =============================================================================
// TrackBar1のOnClickイベント処理
// X軸方向の値に加算する値の設定
// =============================================================================
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.XAddValue := TrackBar1.Position / 100.0 ;
end ;
// =============================================================================
// TrackBar2のOnClickイベント処理
// Y軸方向の値に加算する値の設定
// =============================================================================
procedure TForm1.TrackBar2Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.YAddValue := TrackBar2.Position / 100.0 ;
end ;
{ TMyPanel }
// -----------------------------------------------------------------------------
// コンストラクタ
// 各種プロパティの初期化
// -----------------------------------------------------------------------------
constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited ;
FXAddValue := 0.0 ;
FYAddValue := 0.0 ;
end ;
// -----------------------------------------------------------------------------
// XAddValueプロパティ設定用メソッド
// X軸方向の値に加算する値の設定
// -----------------------------------------------------------------------------
procedure TMyPanel.SetXAddValue(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FXAddValue <> Value then begin
FXAddValue := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// YAddValueプロパティ設定用メソッド
// Y軸方向の値に加算する値の設定
// -----------------------------------------------------------------------------
procedure TMyPanel.SetYAddValue(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FYAddValue <> Value then begin
FYAddValue := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// TMyPanelクラスのPaintメソッド
// 実際の描画コード
// -----------------------------------------------------------------------------
procedure TMyPanel.Paint;
var
LObjWidth : Integer;
LObjHeight : Integer;
LObjRect : TGPRect;
LXLocation : Integer;
LYLocation : Integer;
LGPGraphic : TGPGraphics;
LGPBrush : TGPHatchBrush;
LGPFontFamily : TGPFontFamily;
LGPStrFormat : TGPStringFormat;
LGPPath : TGPGraphicsPath;
LGPMatrix : TGPMatrix;
LGPPen : TGPPen;
LColor : Cardinal;
begin
inherited ;
// 描画する四角形と楕円の領域とサイズ
LObjWidth := 130 ;
LObjHeight := 100 ;
LObjRect := MakeRect(0 , 0 , LObjWidth, LObjHeight);
// 座標原点位置の値
LXLocation := Width div 2 ;
LYLocation := Height div 2 ;
// このTMyPanelのCanvasを描画先にしてTGPGraphicsのインスタンスを生成
LGPGraphic := TGPGraphics.Create(Canvas.Handle);
// 座標の原点を (FXLocation, FYLocation) に移動する
LGPGraphic.TranslateTransform(LXLocation, LYLocation);
// ブラシを生成
LColor := ColorRefToARGB($804000 );
LGPPen := TGPPen.Create(LColor, 1 );
LGPBrush := TGPHatchBrush.Create(HatchStyle30Percent, aclWhite, LColor);
// 文字列の書式等を設定
LGPFontFamily := TGPFontFamily.Create('Arial Black' );
LGPStrFormat := TGPStringFormat.Create;
LGPStrFormat.SetAlignment(StringAlignmentCenter);
LGPStrFormat.SetLineAlignment(StringAlignmentCenter);
// パスを生成して四角形と楕円と文字列を追加
LGPPath := TGPGraphicsPath.Create;
LGPPath.AddRectangle(LObjRect);
LGPPath.AddEllipse(LObjRect);
LGPPath.AddString('DELPHI' ,
-1 ,
LGPFontFamily,
FontStyleRegular,
25 ,
LObjRect,
LGPStrFormat);
// TGPMatrixを生成して要素を代入
LGPMatrix := TGPMatrix.Create;
// マトリックスの情報をパスに渡して,パスを描画
LGPMatrix.SetElements(1.0 , FYAddValue,
FXAddValue, 1.0 ,
0.0 , 0.0 );
LGPPath.Transform(LGPMatrix);
LGPGraphic.FillPath(LGPBrush, LGPPath);
LGPGraphic.DrawPath(LGPPen, LGPPath);
// 座標原点を交差する座標軸を描く
LGPPen.SetColor(aclBlack);
LGPPen.SetWidth(1.0 );
LGPPen.SetDashStyle(DashStyleDash);
LGPGraphic.DrawLine(LGPPen, 0 , -LYLocation, 0 , LYLocation);
LGPGraphic.DrawLine(LGPPen, -LXLocation, 0 , LXLocation, 0 );
// Createしたオブジェクトは解放する
LGPGraphic.Free;
LGPBrush.Free;
LGPFontFamily.Free;
LGPStrFormat.Free;
LGPPath.Free;
LGPMatrix.Free;
LGPPen.Free;
end ;
end .
04_ TGPMatrix による画像の平行四辺形領域描画
上のサンプルと同じ行列演算によって,画像を傾斜して,平行四辺形の描画領域とした例です.
図12
設計時画面
図13
実行開始画面
図14
実行結果例
リスト4
TGPMatrix による画像の平行四辺形領域描画
copy code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, GDIPAPI, GDIPOBJ, ComCtrls;
type
TMyPanel = class (TPanel)
private
FXAddValue : Single;
FYAddValue : Single;
procedure SetXAddValue(const Value: Single);
procedure SetYAddValue(const Value: Single);
protected
procedure Paint; override ;
public
constructor Create(AOwner: TComponent); override ;
property XAddValue : Single read FXAddValue write SetXAddValue;
property YAddValue : Single read FYAddValue write SetYAddValue;
end ;
TForm1 = class (TForm)
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
private
{ Private 宣言 }
MyPanel : TMyPanel;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// =============================================================================
// フォーム生成時の処理
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := 'GDI+ TGPMatrix 平行四辺形の描画領域画像' ;
// 描画するコントロールを生成
MyPanel := TMyPanel.Create(Self);
with MyPanel do begin
Parent := Self;
SetBounds(5 , 70 , Self.ClientWidth - 10 , Self.ClientHeight - 75 );
DoubleBuffered := True;
ControlStyle := MyPanel.ControlStyle + [csOpaque];
BevelOuter := bvNone;
Visible := True;
Color := clWhite;
ParentBackground := False;
Anchors := [akLeft, akTop, akRight, akBottom];
end ;
// X軸方向の値に加算する値の設定
with TrackBar1 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -500 ;
Max := 500 ;
Position := 0 ;
end ;
// Y軸方向の値に加算する値の設定
with TrackBar2 do begin
ShowSelRange := False;
TickStyle := tsNone;
Height := 26 ;
Min := -500 ;
Max := 500 ;
Position := 0 ;
end ;
end ;
// =============================================================================
// TrackBar1のOnClickイベント処理
// =============================================================================
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.XAddValue := TrackBar1.Position / 100.0 ;
end ;
// =============================================================================
// TrackBar2のOnClickイベント処理
// =============================================================================
procedure TForm1.TrackBar2Change(Sender: TObject);
begin
if not Assigned(MyPanel) then exit;
MyPanel.YAddValue := TrackBar2.Position / 100.0 ;
end ;
{ TMyPanel }
// -----------------------------------------------------------------------------
// コンストラクタ
// 各種プロパティの初期化
// -----------------------------------------------------------------------------
constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited ;
FXAddValue := 0.0 ;
FYAddValue := 0.0 ;
end ;
// -----------------------------------------------------------------------------
// XAddValueプロパティ設定用メソッド
// X軸方向の値に加算する値の設定
// -----------------------------------------------------------------------------
procedure TMyPanel.SetXAddValue(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FXAddValue <> Value then begin
FXAddValue := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// YAddValueプロパティ設定用メソッド
// Y軸方向の値に加算する値の設定
// -----------------------------------------------------------------------------
procedure TMyPanel.SetYAddValue(const Value: Single);
begin
if not Assigned(Parent) then exit;
if FYAddValue <> Value then begin
FYAddValue := Value;
Invalidate;
end ;
end ;
// -----------------------------------------------------------------------------
// TMyPanelクラスのPaintメソッド
// 実際の描画コード
// -----------------------------------------------------------------------------
procedure TMyPanel.Paint;
var
LImageFilePath : String ;
LObjWidth : Integer;
LObjHeight : Integer;
LXLocation : Integer;
LYLocation : Integer;
LGPImage : TGPImage;
LGPGraphic : TGPGraphics;
LGPMatrix : TGPMatrix;
begin
inherited ;
LObjWidth := 192 ;
LObjHeight := 144 ;
LXLocation := Width div 2 ;
LYLocation := Height div 2 ;
LImageFilePath := ExtractFilePath(ParamStr(0 )) + 'Hachi.bmp' ;
LGPImage := TGPImage.Create(LImageFilePath);
LGPGraphic := TGPGraphics.Create(Canvas.Handle);
LGPMatrix := TGPMatrix.Create;
LGPMatrix.SetElements(1.0 , FYAddValue,
FXAddValue, 1.0 ,
LXLocation, LYLocation);
LGPGraphic.SetTransform(LGPMatrix);
LGPGraphic.DrawImage(LGPImage,
- LObjWidth div 2 ,
- LObjHeight div 2 ,
LObjWidth,
LObjHeight);
LGPImage.Free;
LGPGraphic.Free;
LGPMatrix.Free;
end ;
end .
TGPImage と TGPBitmap のオーバーロード関数に,領域指定を 3 点で指定する関数があります.
平行四辺形は,3 点を指定すれば,残りの点は自動的に決まります.これを使用しても,画像を傾斜して描画できます.その確認用のサンプルです.
図15
実行画面
描画座標の指定を変更すると,例えば次のような図となります.
このコードでは,座標値の数値は変えずに,格納する配列の要素だけを変えています.
LPoints[0 ] := MakePoint( 30.0 , 50.0 );
LPoints[2 ] := MakePoint(250.0 , 20.0 );
LPoints[1 ] := MakePoint( 90.0 , 200.0 );
図16
実行画面
copy code
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, GDIPAPI, GDIPOBJ, ComCtrls;
type
TMyPanel = class (TPanel)
protected
procedure Paint; override ;
end ;
TForm1 = class (TForm)
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
MyPanel : TMyPanel;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// =============================================================================
// フォーム生成時の処理
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := 'GDI+ 3 点で領域指定した傾斜イメージ' ;
// 描画するコントロールを生成
MyPanel := TMyPanel.Create(Self);
with MyPanel do begin
Parent := Self;
SetBounds(5 , 5 , Self.ClientWidth - 10 , Self.ClientHeight - 10 );
DoubleBuffered := True;
ControlStyle := MyPanel.ControlStyle + [csOpaque];
BevelOuter := bvNone;
Visible := True;
Color := clWhite;
ParentBackground := False;
Anchors := [akLeft, akTop, akRight, akBottom];
end ;
end ;
{ TMyPanel }
// -----------------------------------------------------------------------------
// TMyPanelクラスのPaintメソッド
// 実際の描画コード
//
// DrawImage関数のテスト
// 描画領域に3点を与えると,描画領域は平行四辺形となる
// -----------------------------------------------------------------------------
procedure TMyPanel.Paint;
var
LPoints : array [0 ..2 ] of TGPPointF;
LImageFilePath : String ;
LGPImage : TGPImage;
LGPGraphic : TGPGraphics;
begin
inherited ;
LPoints[0 ] := MakePoint( 30.0 , 50.0 );
LPoints[1 ] := MakePoint(250.0 , 20.0 );
LPoints[2 ] := MakePoint( 90.0 , 200.0 );
// 画像ファイルを指定.TGPImaageインスタンスを生成して読み込む
LImageFilePath := ExtractFilePath(ParamStr(0 )) + 'Hachi.bmp' ;
LGPImage := TGPImage.Create(LImageFilePath);
LGPGraphic := TGPGraphics.Create(Canvas.Handle);
LGPGraphic.DrawImage(LGPImage, PGPPointF(@LPoints), Length(LPoints));
// Createしたオブジェクトは解放する
LGPImage.Free;
LGPGraphic.Free;
end ;
end .