Delphi Programming / Object Pascal
[掲載 2012年10月25日] [更新 2014年07月09日] GDI+ 関係サンプル |
GDI+ 関係サンプル
概要 |
動作確認等 |
サンプルよって異なる
全てのサンプルがダウンロード可能 (実行ファイル同梱) |
|
gdiplus.zip [1,144 KB] 2002年02月15日版 (Delphi XE 以前用) |
GDI+ は Windows XP で実装されたグラフィクスサブシステムですです.
GDI+を使うと,.NET Frameworkと同等のグラフィック機能を Windows API ベースのプログラムから使用することができます.GDI+ を使用しない場合は GDI による描画ということになります.
GDI+ の関数類は,Gdiplus.dll が提供しています.Delphi XE2 では GDI+ の API を利用するためライブラリが標準実装されました.
Microsoft Office 関連でも,少なくも Office XP, 2003 では GDI+ を使用しています.GDI+ のサンプルは,ネット上に多くありますが,若干のテストプログラムを作成してみました.
Delphi で使用可能な GDI+ Library には,この他,.NET Framework 互換の
Delphi GDI+ Library for use with Delphi 2009 (version 1.2)
があります.MSDN の記事のほとんどが .NET Framework 対応のものですから,今後はこちらの方の利用を考えてもいいのかも知れません.Delphi XE2 に実装されているのが .NET 互換の方ではないので,今回は使用しませんでした.
上のリンクの Delphi 2009 以降で使用可能な .NET 互換の GDI+ には,Blur (ブラー) というガウスばかしのクラスがありますが,本サンプルで使用している GDI+ には実装されていません.Delphi XE2 の GDI+ ライブラリには,拡張された Blur クラスが実装されています.
GDI+ ライブラリの機能を使用するには,uses に GDIPAPI, GDIPOBJ 等を追加します.
|
Delphi XE 以前で GDI+ ライブラリを使用する
( gdiplus.zip ) |
Delphi XE 以前で GDI+を使用するには,本ページから GDI+ ライブラリ (2002年02月15日版) を別途ダウンロードしてください.
これは progdigy.com というサイトで提供されていたものですが,2013年07月11日現在入手できません.MPL1.1 のライセンスに基づき,当サイトで再配布しています..
次の手順で導入します.
- gdiplus.zip をダウンロード
- ダウンロードした gdiplus.zip を適当なフォルダに解凍
- 解凍したフォルダ内の [pas] フォルダにパスを通す
- uses に GDIPAPI と GDIPOBJ を追加する
Delphi 7 以前であれば,このまま使用できます.それ以降のバージョンでは,以下のエラーが発生して,プロジェクトのコンパイルに失敗します. |
[DCC エラー] DirectDraw.pas(358): E2154 'IDirectDrawSurface' 型は終了処理が必要です - 構造体の可変部に置くことは許されません |
ダウンロードした GDI+ のバージョン定義ファイル Jedi.inc は Delphi 7 までの対応です.そのために必要なコードが実行されないのが原因で発生します (情報源 : Dephi-fan の GDI+ を使う).
そこで,筆者は次のリストのように修正しました.つまり,Delphi のバージョンを全て Delphi 7 にごまかす設定です.この修正をしても,[ヒント] や [警告] は表示されますが,使用可能です. |
リスト1
[pas] フォルダ内の Jedi.inc を修正.Delphi 7 以降全てで使用可能に
VERXXX to COMPILERX, DELPHIX and BCBX mappings
の部分を以下に変更 |
//------------------------------------------------------------------------------
// VERXXX to COMPILERX, DELPHIX and BCBX mappings
//------------------------------------------------------------------------------
{$IF CompilerVersion > 14.99}
{$DEFINE COMPILER7}
{$IFDEF BCB}
{$DEFINE BCB7}
{$DEFINE BCB}
{$ELSE}
{$DEFINE DELPHI7}
{$DEFINE DELPHI}
{$ENDIF}
{$IFEND}
どうしても [ヒント] や [警告] が気になるのであれば,
は,大文字あるいは小文字に修正します.これは,主にメソッド名の先頭文字です.また,
は,下のコードのように,reintroduce 指令を追加します. |
function Equals(region: TGPRegion; g: TGPGraphics): BOOL; reintroduce;
GDI+ のグラフィックスのオブジェクト,TGPGraphics のインスタンス (実体) は,以下のように,描画対象の TCanvas のハンドルを引数に指定して作成します.
例えば,TBitmap の Canvas に描画する場合は,TBitmap.Canvas.Handle とします.
TImage の Canvas に描画する場合は,TImage.Canvas.Handle とします.
TBitmap や TImage はクラス名です.実際にはそれらのインスタンスの名前とします,Image1 であれば Image1.Canvas.Handle となります. |
//描画先を指定してTGPGraphicsオブジェクトを生成する
LGPGraphic := TGPGraphics.Create(Canvas.Handle);
そして,この TGPGraphics の描画用のプロパティである色等を設定し,描画用のメソッドで図形や画像を描画します.すると,指定した TCanvas に図形なり画像が描画されることになります.描画先が TImage 等であれば描画結果は目に見えます.
TBitmap の場合は,描画コードを実行しても実際には目には見えません.処理結果としての,そのビットマップを何かに表示するとか,保存するとことになります.
ペンやブラシ等の設定は,TCanvas のようなプロパティではなく,それそれのオブジェクトを生成して設定します.ペンや線のプロパティを設定するためのオブジェクト類は,この TGPGraphics のオブジェクトがなくても,独立して設定できます.
|
//描画座標値をポイントで指定
P1 := MakePoint(20, 150);
P2 := MakePoint(200, 150);
//TGPPenのペンの設定で線を引く(描画する)
LGPGraphic.DrawLine(LGPPen, P1, P2);
サンプルの多くは,フォームに配置したパネル,あるいは,TPanel を継承した TMyPanel というコントロールの Paint メソッドで,その Canvas に画像や図形を描画しています.
アプリケーションを開発する際,多くの場合,複数のフォームあるいはユニットを使用します.そしてそれらのフォームあるいはユニットと変数のやりとりが必要となります.
この時,グローバルな変数を介するよりも,プロパティ,あるいはメソッド類で行うのが一般的です.このことを意識して TPanel の派生クラスを作成して,他のフォーム,ユニット内のクラスとのやりとりの代わりとしています.
描画コード自体は Paint メソッド以外にはありません.フォームの OnPaint イベント,あるいは,TPaintBox の OnPaint イベント等に,この TMyPanel メソッドのコードをコピーして貼り付け,コード内のプロパティ等の変数に直接値を代入すれば,ネット上の多くのサンプル,デモプログラムと同じように扱えます.
TImage に描画するサンプルもありますが,TImage は内部で「オフスクリーンビットマップ」というビットマップを生成して描画内容を表示します.そのため,描画内容を変更する際,一度描画内容をクリアしてから再度描画コードを実行するという作業が必要な場合があります.
TImage は,他のウィンドウが上に重なっても,描画の更新を内部で自動で実行してくれます.また重ね描画も自動で処理してくれます.GDI+ で描画する場合は,追加の描画もコードを追加しなければなりません.そのため,TImage のような追加描画の機能を実装するには,オフスクリーンビットマップのような仕組みが必要となることがあります.
|
[備考]
ほとんどのサンプルは,継承元を TPanel から TGraphicControl の TPaintBox に変更してもそのまま動作しますが,座標値の変換が必要な場合があります.
|
GDI+ の描画コードをプリンタに出力する時は,印刷のコーディングにもよりますが,次のように,描画コードを実行する前にマッピングが必要な場合があります.GDI+ の関数の中には,UnitPixelを引数で指定するものがあります.その場合は必要ありません.
この現象は,.NET 互換の GDI+ では必要ありません.なくても正しく印刷できます. |
リスト3
GDI+ を使用した描画コードを印刷する際は,描画コードを実行する前にマッピングが必要 |
procedure TplResizeZLine.DrawRoutine(ACanvas: TCanvas; OffSetX: Integer=0;
OffSetY: Integer=0);
var
LGraphic : TGPGraphics;
begin
//----------- 略 -------------------------
LGraphic := TGPGraphics.Create(ACanvas.Handle);
SetMapMode (ACanvas.Handle, MM_TEXT);
LGraphic.SetPageUnit(UnitPixel);
//----------- 描画コード ------------------
end;
サンプルプログラムのダウンロード方法とブロックの解除 |
各ページの上の方,最初の方に,下図のような画像があります.これをクリックしてください.サンプル単位ではなく,そのページのサンプルの一括ダウンロードとなっています.
各サンプルの個別ダウンロードの要望がありましたが,対応の予定はありません.
ダウンロードしたら [ブロックの解除] をしてください.
|
記事内のコードをコピーして利用する場合は,各サンプルコードの左上のコピーボタンをクリックするとクリップボードにコピーできます.
|
|