DelphiでCanvas描画|TBitmap・TCanvasを使った図形・文字の描画サンプル(VCL/FMXL対応)
DelphiでCanvasを使って図形や文字を描画する方法を、VCLとFMXの両環境で紹介します。
この記事では、TBitmapを使った塗りつぶし(FillRect)、線の描画、文字の出力(TextRect/FillText)など、基本的な描画処理をサンプルコード付きで解説します。
また、VCL環境でのジオメトリックペン(ExtCreatePen)によるカスタム描画や、FMX環境でのTImageとの連携によるCanvas操作も取り上げています。
描画サイズや色指定、フォント設定など、細かな制御方法も含めて網羅しています。
ソースコード
VCLの場合
「ファイル」⇒「新規作成」⇒「Windows VCLアプリケーション」をクリックフォームにTImageとTButtonをドラッグ&ドロップする

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; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var r:TRect; text:String; begin //■■■ Image1の初期設定 ■■■ //Image1の幅高さ設定 Image1.Width:=200; Image1.Height:=200; //TImageが内部保持画像データ(TBitmap)の幅高さ設定 Image1.Picture.Bitmap.Width:=100; Image1.Picture.Bitmap.Height:=100; //RGB(24bit色)に設定する Image1.Picture.Bitmap.PixelFormat:=TPixelFormat.pf24bit; //表示時に画像データの縦横比を保持するよう設定 Image1.Proportional:=True; //TImageのサイズに画像を拡大又は縮小表示するように設定 //つまり、100×100の画像を200×200に引き延ばして表示する Image1.Stretch:=True;
//■■■ 塗りつぶし ■■■ Image1.Picture.Bitmap.Canvas.Brush.Color:=$00ff00;//緑 Image1.Picture.Bitmap.Canvas.Brush.Style:=TBrushStyle.bsSolid; //塗りつぶす(0,0)-(100-1,100-1)の領域 Image1.Picture.Bitmap.Canvas.FillRect( Rect(0,0,100,100) );
//■■■ 線を描画する ■■■ //線(ペン)の設定 Image1.Picture.Bitmap.Canvas.Pen.Width:=1; Image1.Picture.Bitmap.Canvas.Pen.Style:=TPenStyle.psSolid; Image1.Picture.Bitmap.Canvas.Pen.Color:=$ff0000;//青色 //(0,0)-(100-1,100-1)に線を引き、ペンを100,100の位置に移動 Image1.Picture.Bitmap.Canvas.MoveTo(0,0); Image1.Picture.Bitmap.Canvas.LineTo(100,100);
//■■■ 文字を描画する ■■■ //色、スタイル設定 Image1.Picture.Bitmap.Canvas.Font.Color:=$0000ff;//赤色 Image1.Picture.Bitmap.Canvas.Brush.Style:=TBrushStyle.bsSolid; //フォントサイズのピクセル単位で設定 Image1.Picture.Bitmap.Canvas.Font.Height:=10; //10ピクセル //太字設定 Image1.Picture.Bitmap.Canvas.Font.Style:=[TFontStyle.fsBold]; //フォント名設定 Image1.Picture.Bitmap.Canvas.Font.Name:='MS Pゴシック'; //文字の出力 text:='出力しますが自動改行でクリッピングします'; r:=Rect(0,20,50,60);//出力範囲 Image1.Picture.Bitmap.Canvas.TextRect( r, text, [ TTextFormats.tfLeft,TTextFormats.tfTop, TTextFormats.tfWordBreak ] );
end; end.
実行
実行して、Button1をクリック
色の指定
// uses に Vcl.Graphics が存在する場合Panel1.Color := clRed;
// 16 進数で指定する場合 (緑)
Panel1.Color := $00FF00;
独自の模様(パターン)で塗りつぶしを行う場合
procedure TForm1.Button2Click(Sender: TObject);
var pattern:TBitmap;
begin
//■■■ Image1の初期設定 ■■■
//Image1の幅高さ設定
Image1.Width:=200;
Image1.Height:=200;
//TImageが内部保持画像データ(TBitmap)の幅高さ設定
Image1.Picture.Bitmap.Width:=100;
Image1.Picture.Bitmap.Height:=100;
//RGB(24bit色)に設定する
Image1.Picture.Bitmap.PixelFormat:=TPixelFormat.pf24bit;
//表示時に画像データの縦横比を保持するよう設定
Image1.Proportional:=True;
//TImageのサイズに画像を拡大又は縮小表示するように設定
//つまり、100×100の画像を200×200に引き延ばして表示する
Image1.Stretch:=True;
//模様(パターン)用のTBitmapの作成
pattern:=TBitmap.Create;
try
//パターン用TBitmapはサイズ8x8までで、それ以上は無視される
pattern.Width:=8;
pattern.Height:=8;
pattern.Canvas.Brush.Color:=RGB($FF,$FF,$FF);
pattern.Canvas.FillRect(Rect(0,0,8,8));
pattern.Canvas.Brush.Color:=RGB($77,$77,$77);
pattern.Canvas.FillRect(Rect(0,0,4,4));
pattern.Canvas.FillRect(Rect(4,4,8,8));
//■■■ 指定した模様(パターン)で塗りつぶし ■■■
Image1.Picture.Bitmap.Canvas.Brush.Bitmap:=pattern;
//塗りつぶす(0,0)-(100-1,100-1)の領域
Image1.Picture.Bitmap.Canvas.FillRect(
Rect(0,0,100,100)
);
Image1.Picture.Bitmap.Canvas.Brush.Bitmap:=nil;
finally
pattern.Free;
end;
end;
デフォルトのコスメティックペンではなく、ジオメトリックペンを使う場合
procedure TForm1.Button3Click(Sender: TObject);
var LogBrush:TLogBrush;
PenStyle:Cardinal;
pen:HPEN;
OldPen:HPEN;
ArrPoint:Array[0..2] of TPoint;
begin
//■■■ Image1の初期設定 ■■■
//Image1の幅高さ設定
Image1.Width:=200;
Image1.Height:=200;
//TImageが内部保持画像データ(TBitmap)の幅高さ設定
Image1.Picture.Bitmap.Width:=100;
Image1.Picture.Bitmap.Height:=100;
//RGB(24bit色)に設定する
Image1.Picture.Bitmap.PixelFormat:=TPixelFormat.pf24bit;
//表示時に画像データの縦横比を保持するよう設定
Image1.Proportional:=True;
//TImageのサイズに画像を拡大又は縮小表示するように設定
//つまり、100×100の画像を200×200に引き延ばして表示する
Image1.Stretch:=True;
//既存のコスメティックペンを保存
OldPen:=Image1.Picture.Bitmap.Canvas.Pen.Handle;
//ジオメトリックペンの作成
LogBrush.lbStyle:=BS_SOLID;
LogBrush.lbColor:=RGB($0,$cc,$cc);
LogBrush.lbHatch:=0;
PenStyle:=PS_GEOMETRIC+PS_DASH+PS_ENDCAP_ROUND+PS_JOIN_ROUND;
pen:=ExtCreatePen(PenStyle,3,LogBrush,0,nil);
//作成したジオメトリックペンを使用できるよう設定
Image1.Picture.Bitmap.Canvas.Pen.Handle:=pen;
//ポリゴンを表示する
ArrPoint[0].X:=0;
ArrPoint[0].Y:=0;
ArrPoint[1].X:=99;
ArrPoint[1].Y:=30;
ArrPoint[2].X:=40;
ArrPoint[2].Y:=96;
Image1.Picture.Bitmap.Canvas.Polygon(ArrPoint);
//既存のコスメティックペンに戻す
Image1.Picture.Bitmap.Canvas.Pen.Handle:=OldPen;
//作成したジオメトリックペンの破棄
DeleteObject(pen);
end;
FMXの場合
「ファイル」⇒「新規作成」⇒「マルチデバイスアプリケーション」をクリック「空のアプリケーション」をクリック
フォームにTImageとTButtonをドラッグ&ドロップする

unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects; type TForm1 = class(TForm) Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private { private 宣言 } public { public 宣言 } end; var Form1: TForm1; implementation {$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject); begin //■■■ Image1の初期設定 ■■■ //Image1の幅高さ設定 Image1.Width:=200; Image1.Height:=200; //TImageが内部で保持している画像データ(TBitmap)の幅高さ設定 Image1.Bitmap.Width:=100; Image1.Bitmap.Height:=100; //FMXではBGR(24bit色)に出来ない BGRA固定と思われる // 不可Image1.Bitmap.PixelFormat:=TPixelFormat.BGR; //表示時に画像の縦横比を保持するよう設定 //TImageのサイズに画像データを拡大又は縮小表示するように設定 //つまり、100×100の画像を200×200に引き延ばして表示する Image1.WrapMode:=TImageWrapMode.Fit; //描画前に呼び出す Image1.Bitmap.Canvas.BeginScene();
//■■■ 塗りつぶし ■■■ Image1.Bitmap.Canvas.Fill.Color:=$ff00ff00;//緑 Image1.Bitmap.Canvas.Fill.Kind:=TBrushKind.Solid; //塗りつぶす(0,0)-(99,99)の領域 Image1.Bitmap.Canvas.FillRect( RectF(0,0,99,99),0,0,[],1 );
//■■■ 線を描画する ■■■ //線(ペン)の設定 Image1.Bitmap.Canvas.Stroke.Thickness:=1; Image1.Bitmap.Canvas.Stroke.Dash:=TStrokeDash.Solid; Image1.Bitmap.Canvas.Stroke.Color:=$ff0000ff;//青色 //(0,0)-(99,99)に線を引く Image1.Bitmap.Canvas.DrawLine(PointF(0,0),PointF(99,99),1);
//■■■ 文字を描画する ■■■ //色、スタイル設定 Image1.Bitmap.Canvas.Fill.Color:=$ffff0000;//赤色 Image1.Bitmap.Canvas.Fill.Kind:=TBrushKind.Solid; //フォントサイズのピクセル単位で設定 {$IFDEF MSWINDOWS} //MS-Windowsの場合は÷72×96が必要 Image1.Bitmap.Canvas.Font.Size:= Image1.Bitmap.Canvas.Font.Size/ Image1.Bitmap.Canvas.TextHeight('M')/72*96* 10;//10ピクセル {$ELSE} Image1.Bitmap.Canvas.Font.Size:= Image1.Bitmap.Canvas.Font.Size/ Image1.Bitmap.Canvas.TextHeight('M')* 10;//10ピクセル {$ENDIF} //太字設定 Image1.Bitmap.Canvas.Font.Style:=[TFontStyle.fsBold]; //フォント名設定 Image1.Bitmap.Canvas.Font.Family:='MS Pゴシック'; //文字の出力 Image1.Bitmap.Canvas.FillText( RectF(0,20,50,60), '出力しますが自動改行でクリッピングします',true,1,[], TTextAlign.Leading,TTextAlign.Leading );
//描画処理の終了 Image1.Bitmap.canvas.EndScene(); end; end.
実行
実行して、Button1をクリック
色の指定
// uses に System.UITypes が存在する場合Rectangle1.Fill.Color := TAlphaColorRec.Red;
// uses に Sysytem.UIConsts が存在する場合
Rectangle1.Fill.Color := claBlue;
// 16 進数で指定する場合 (緑)
Rectangle1.Fill.Color := $FF00FF00;
