TDirect2DCanvasでTBitmapに高速描画 ~Delphiソースコード集
Direct2Dは描画操作をCPUではなくGPUに転送します。よって多くの場合、高速に処理できます。
またDirect2Dのキャンバス(TDirect2DCanvas)を使うと、半透明色が使用でき、アンチエイリアスを有効にすることも出来ます。
ただし、Windows7以降、かつDelphi2010以降でなければ使用できません。
プロジェクトの作成と画面設計
プロジェクトを新規作成(VCLアプリケーション)し、フォーム(Form1)にTButtonを1個、TImageを1個を配置する。
ソースコードの記述
TButton1をダブルクリックして、以下ソースコードを記述する。unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; Image1: TImage; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} uses Vcl.Direct2D, Winapi.D2D1, System.Math, Vcl.Imaging.jpeg; procedure TForm1.Button1Click(Sender: TObject); var D2Canvas:TDirect2DCanvas; ptf:TD2DPoint2f; jpg:TJpegImage; D2D1SolidColorBrush:ID2D1SolidColorBrush; D2D1StrokeStyle:ID2D1StrokeStyle; begin if not TDirect2DCanvas.Supported then begin ShowMessage('Direct2Dは使えません'); exit; end; //サイズの設定 Image1.Width:=320; Image1.Height:=320; Image1.Picture.Bitmap.Width:=Image1.Width; Image1.Picture.Bitmap.Height:=Image1.Height; Image1.Picture.Bitmap.PixelFormat:=pf24bit; //Direct2Dキャンバスの作成 D2Canvas:= TDirect2DCanvas.Create( Image1.Picture.Bitmap.Canvas, Rect( 0,0, Image1.Picture.Bitmap.Width, Image1.Picture.Bitmap.Height ) ); //描画の開始 D2Canvas.BeginDraw; //ブラシの設定 D2Canvas.Brush.Color:=clWhite; D2Canvas.Brush.Style:=bsSolid; D2Canvas.Brush.Handle.SetOpacity(1);//不透明度100% //ペンの設定 D2Canvas.Pen.Color:=clBlue; D2Canvas.Pen.Style:=psSolid; D2Canvas.Pen.Width:=4; //アンチエイリアスを無効にする D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); //■矩形の描画 D2Canvas.Rectangle( 0,0, Image1.Picture.Bitmap.Width, Image1.Picture.Bitmap.Height ); //ブラシの設定 D2Canvas.Brush.Color:=clYellow; D2Canvas.Brush.Handle.SetOpacity(0.5);//不透明度50% //ペンの設定 D2Canvas.Pen.Brush.Handle.SetOpacity(0.5);//不透明度50% D2Canvas.Pen.Width:=12; //■線の描画 //アンチエイリアスを有効に戻す D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); //直線を描画 D2Canvas.MoveTo(0,0); D2Canvas.LineTo( 100, Image1.Picture.Bitmap.Height-1 ); //アンチエイリアスを無効にする D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); //直線を描画 D2Canvas.MoveTo(20,0); D2Canvas.LineTo( 120, Image1.Picture.Bitmap.Height-1 ); //■RenderTarget.DrawLineで線を描画 //青色の不透明度50%のブラシを「D2D1SolidColorBrush」に作成 D2Canvas.RenderTarget.CreateSolidColorBrush( D2D1ColorF(clBlue, 0.5), nil, D2D1SolidColorBrush); //線の形状を「D2D1StrokeStyle」に作成 D2DFactory.CreateStrokeStyle( D2D1StrokeStyleProperties( D2D1_CAP_STYLE_ROUND, //開始点の形状(丸くする) D2D1_CAP_STYLE_ROUND, //終了点の形状(丸くする) D2D1_CAP_STYLE_TRIANGLE,//破線の形状(三角形に) D2D1_LINE_JOIN_ROUND, //線の接続点の形状(丸くする) 10.0, //マイター(線の接合点の尖った部分)の限界値 D2D1_DASH_STYLE_DASH, //破線を指定 0 ), nil, 0, D2D1StrokeStyle ); //直線を描画 D2Canvas.RenderTarget.DrawLine( D2D1PointF(50,20), D2D1PointF(130,Image1.Picture.Bitmap.Height-56), D2D1SolidColorBrush, 12, D2D1StrokeStyle ); //■角丸矩形を描画 //アンチエイリアスを有効に戻す D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); //角丸矩形を描画 D2Canvas.RoundRect( Rect(180,100,280,140), 8,8 ); //アンチエイリアスを無効にする D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); //角丸矩形を描画 D2Canvas.RoundRect( Rect(200,120,300,160), 8,8 ); //■楕円を描画 //アンチエイリアスを有効に戻す D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); //楕円の描画 D2Canvas.Ellipse(180,180,260,280); //アンチエイリアスを無効にする D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); //楕円の描画 D2Canvas.Ellipse(200,200,280,300); //■テキストを描画 //テキスト出力時にアンチエイリアスを有効にする D2Canvas.RenderTarget.SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE); //ブラシを透明にする D2Canvas.Brush.Style:=bsClear; //フォントの設定 D2Canvas.Font.Brush.Handle.SetOpacity(0.7); D2Canvas.Font.Size:=24; //(pt) ptf.x:=40; ptf.y:=160; //変換を30度回転に設定する D2Canvas.RenderTarget.SetTransform(TD2DMatrix3x2F.Rotation(30,ptf)); //文字の描画 D2Canvas.TextOut(trunc(ptf.x),trunc(ptf.y),'文字列'); //テキスト出力時にアンチエイリアスを無効にする D2Canvas.RenderTarget.SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED); //変換を元に戻す D2Canvas.RenderTarget.SetTransform(TD2DMatrix3x2F.Rotation(0,ptf)); //文字の描画 D2Canvas.TextOut(trunc(ptf.x),trunc(ptf.y),'文字列'); //JPEG画像を描画 (test.jpg画像を用意してください) //アンチエイリアスを有効に戻す D2Canvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); jpg:=TJPEGImage.Create; try jpg.LoadFromFile('..\..\test.jpg'); ptf.x:=200; ptf.y:=10; //変換を20度回転に設定する D2Canvas.RenderTarget.SetTransform(TD2DMatrix3x2F.Rotation(20,ptf)); D2Canvas.StretchDraw( Rect( trunc(ptf.x),trunc(ptf.y), trunc(ptf.x)+80,trunc(ptf.y+80*jpg.Height/jpg.Width) ), jpg, 180 //不透明度(0~255) ); //変換を元に戻す D2Canvas.RenderTarget.SetTransform(TD2DMatrix3x2F.Rotation(0,ptf)); finally jpg.Free; end; //描画の終了 D2Canvas.EndDraw; //Direct2Dキャンバスの破棄 D2Canvas.Free; end; end.
実行する
実行ボタンを押して実行します。(デバッグ実行でもOK)Button1をクリックすると、Image1.picture.bitmapの背景を塗りつぶし、線、角丸矩形、楕円、文字、jpg画像を描画します。
アンチエイリアスの有無で境界がギザギザだったり滑らかだったりしています。
