Windows GDIを使う
拡張メタファイルを作成するにはCreateEnhMetaFileを用いる.
このAPIのプロトタイプは以下のようになっている.
function CreateEnhMetaFile(DC: HDC; p2: PChar; p3: PRect; p4: PChar): HDC;
(p3パラメータに設定する値)= (画面上での画像の寸法[pixel])* (画面の寸法[mm] * 100)/ (画面の寸法[pixel])
mm単位およびpixel単位の画面の寸法はGetDeviceCapsで取得できる. p4は作者名などのオプション文字列へのポインタである.
CreateEnhMetaFileの呼び出しが成功すればメタファイルDCのハンドルが返ってくる. このハンドルを使えば,通常のDCと同じようにメタファイルDCに描画することができる.
描画が終了したらCloseEnhMetaFileにメタファイルDCのハンドルを渡してDCを解放する. CloseEnhMetaFileはメタファイルのハンドルを返す. このハンドルはPlayEnhMetaFileやEnumEnhMetaFileに渡すことができる. メタファイルが不要になったらDeleteEnhMetaFileを呼び出してメタファイルのハンドルを解放しなければならない.
以下にプログラム例を示す.
procedure TForm1.Button1Click(Sender: TObject);
var
MMPerPixelW, MMPerPixelH: Integer;
Index, X, Y: Integer;
RefRect: TRect;
MetafileDC: HDC;
TheMetafile: HMETAFILE;
TheBrush, OldBrush: HBRUSH;
ThePen, OldPen: HPEN;
TheColor: TColor;
begin
MMPerPixelW := MulDiv( GetDeviceCaps( Canvas.Handle, HORZSIZE ), // 1pixelあたりの長さを取得する(0.01mm単位,x方向)
100, GetDeviceCaps( Canvas.Handle, HORZRES ) );
MMPerPixelH := MulDiv( GetDeviceCaps( Canvas.Handle, VERTSIZE ), // 1pixelあたりの長さを取得する(0.01mm単位,y方向)
100, GetDeviceCaps( Canvas.Handle, VERTRES ) );
RefRect.Top := 0;
RefRect.Left := 0;
RefRect.Right := Image1.Width * MMPerPixelW; // Imageの幅
RefRect.Bottom := Image1.Height * MMPerPixelH; // Imageの高さ
MetafileDC := CreateEnhMetaFile( Canvas.Handle, 'meta_gdi.emf', @RefRect, nil ); // メタファイルDCを作成
TheBrush := CreateSolidBrush( clAqua ); // 水色のブラシを作成
OldBrush := SelectObject( MetafileDC, TheBrush ); // DCに選択
FillRect( MetafileDC, RefRect, TheBrush ); // 塗りつぶし
SelectObject( MetafileDC, OldBrush ); // 以前のブラシをDCに選択
DeleteObject( TheBrush ); // 水色のブラシを削除
for Index := 0 to 99 do
begin
TheColor := RGB( Random( 255 ), Random( 255 ), Random( 255 ) ); // 任意の色を設定
ThePen := CreatePen( PS_SOLID, 1, TheColor ); // 実線のペンを作成
TheBrush := CreateSolidBrush( TheColor ); // ブラシを作成
OldPen := SelectObject( MetafileDC, ThePen ); // DCにペンを選択
OldBrush := SelectObject( MetafileDC, TheBrush ); // DCにブラシを選択
X := Random( Image1.Width ); // 任意を座標を設定
Y := Random( Image1.Height );
Ellipse( MetafileDC, X, Y, X + 20, Y + 20 ); // 円を描く
SelectObject( MetafileDC, OldPen );
SelectObject( MetafileDC, OldBrush );
DeleteObject( ThePen );
DeleteObject( TheBrush );
end;
TheMetaFile := CloseEnhMetaFile( MetafileDC ); // メタファイルDCを解放
PlayEnhMetaFile( Image1.Canvas.Handle, TheMetaFile, Image1.Canvas.ClipRect ); // Imageにメタファイルを再生する
DeleteEnhMetaFile( TheMetaFile ); // メタファイルを解放
end;
VCLのTMetaFileクラスはメタファイルを扱うクラスである. ただし,TMetaFileクラス自体にはCanvasプロパティが無いので,実際の描画にはTMetaFileCanvasクラスを用いる.
まずTMetaFileクラスのインスタンスを作成し,EnhancedをTrueに,WidthおよびHeightを適当な値にそれぞれ設定する. 次にTMetaFileCanvasクラスのインスタンスを作成するが,このコンストラクタには 先に作成したTMetaFileのインスタンスおよび参照DCのハンドルを渡す. 参照DCは,TMetaFileのMMWidthおよびMMHeightが未設定の場合に これらを設定するために使われる. 参照DCのハンドルに0が指定された場合,TMetaFileCanvasのコンストラクタはスクリーンDCのハンドルを 使ってMMWidthおよびMMHeightを設定する. この場合,TMetaFileのWidthおよびHeightがなぜか0になってしまうので,描画を始める前にこれらのプロパティを 再設定する必要がある.
あとは通常のCanvasに対する描画と同じように描画を行うことができる. 描画が終了したらTMetaFileCanvasのFreeメソッドを呼び出すことにより, 描画したイメージがTMetaFileクラスのインスタンスに転送される. TMetaFileクラスのインスタンスは,他のCanvasのDrawメソッドに渡すことができる.
以下にプログラム例を示す.
procedure TForm1.Button4Click(Sender: TObject);
var
Metafile: TMetafile;
MetafileCanvas: TMetafileCanvas;
TheColor: TColor;
Index, X, Y: Integer;
RefRect: TRect;
begin
Metafile := TMetafile.Create; // TMetaFileのインスタンスを作成し,
Metafile.Enhanced := True; // EnhancedをTrueに,
Metafile.Width := Image1.Width; // WidthおよびHeightを適当な値に設定する
Metafile.Height := Image1.Height;
MetafileCanvas := TMetafileCanvas.Create( Metafile, 0 ); // TMetaFileCanvasのインスタンスを作成する
MetafileCanvas.Pen.Width := 1;
MetafileCanvas.Pen.Style := psSolid;
MetafileCanvas.Brush.Color := clYellow;
RefRect := Rect( 0, 0, Image1.Width, Image1.Height );
Metafile.Width := Image1.Width; // メタファイルのWidthおよびHeightを再設定する
Metafile.Height := Image1.Height;
MetafileCanvas.FillRect( RefRect );
for Index := 0 to 99 do
begin
TheColor := RGB( Random( 255 ), Random( 255 ), Random( 255 ) );
with MetafileCanvas do
begin
Pen.Color := TheColor;
Brush.Color := TheColor;
X := Random( RefRect.Right );
Y := Random( RefRect.Bottom );
Ellipse( X, Y, X + 20, Y + 20 );
end;
end;
MetafileCanvas.Free; // TMetaFileCanvasのオブジェクトを破棄する
Metafile.SaveToFile( 'meta_vcl.emf' ); // メタファイルを保存する
Image1.Canvas.Draw( 0, 0, Metafile ); // Imageに描画する
Metafile.Free;
end;
できた拡張メタファイルのサイズは,Windows GDI: 15112バイト,VCL: 19132バイトであった.
SEO | [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送 | ||