Graphics Device Interface(グラフィックス・デバイス・インターフェイス、GDI)とは、カーネルおよびユーザー(ウィンドウマネージャ)と協調するWindowsの3つの主要コンポーネント(サブシステム)の1つ。

GDIはグラフィカルオブジェクトの表示と、ディスプレイやプリンターのような出力機器への転送のためのWindows規格である。

## GDI

GDIは直線や曲線の描画、矩形や楕円の描画と塗りつぶし、ビットマップ画像(ラスター画像)の操作、フォントの管理とレンダリング、パレットの制御といった処理を担当する(gdi32.dll)。ウィンドウやメニューなどのような上位レベルの描画については直接関わらず、より上位の user32.dll にあるユーザーサブシステムに任される。

GDIはハードウェアに直接アクセスするデバイスドライバーよりも上位に位置し、デバイスの機能的な調整と抽象化がGDIの役目である。GDIを使うことにより、画面やプリンターなどの多様なデバイスに容易に描画でき、そして各デバイスで適切な表示結果を望める。この機能はWindowsの全てのWYSIWYGアプリケーションの要である。

フリーセルやマインスイーパ(Windows XP以前)のような高速な描画が不要なゲームはGDIを使用していた。しかし、GDIはアニメーションをうまく表示できず(フレームバッファ同期の概念が無い)、3D ラスタライズ機能がないこともあり、ゲーム開発には不向きである。そのため、ゲーム開発では一般的に2D/3D問わず、ハードウェアの機能や性能をより活用できるDirectX (Direct2D/Direct3D) やOpenGL、Vulkanが使われる。

Windows Vista では、GDI アプリケーションは新しい描画エンジンである Desktop Window Manager (DWM) のもとで動作し、GDIコンテンツはいったんシステムメモリ上のビットマップにCPUで描画され、ハードウェアアクセラレーションは用いられない。Windows 7 以降では GDI の一部が再びハードウェアアクセラレートされるようになっているが、DWM が有効になっている必要がある。

## GDI プリンター

GDI プリンター(Winmodem のように Winprinters としても知られている)、特に GDI レーザープリンターは本来プリンターが行う処理の一部をホストコンピュータ (PC) 側で代行する。ホストコンピュータでビットマップイメージを描写し、プリンターにビットマップを転送する。この方式には以下の2つの利点がある。

- 描画処理用 CPU と RAM をプリンターに搭載する費用を節約できる。
- 受け取ったイメージを印刷することに特化することで性能の最適化ができる。

また、以下の点で不利である。

- ホストコンピュータの負荷が高くなる。最近のPCでは問題ないが、古いPCで複雑なドキュメントを印刷する場合は非常に遅くなる場合がある。
- GDI プリンターは通常、プリンターのファームウェアに標準的な印刷機能のエミュレーションを含まない(またはそれを処理できる能力を持たない)。ハイエンドの PCL プリンターや PostScriptプリンターでは、ソフトウェアの互換性やドライバーのバグなどの問題があった場合にドライバーを更新して対応できるが、GDI プリンターでは対応策がない場合がある。
- GDIプリンターは一般的に Windows に限り動作する。例外はあるが、他の OS では原則的に GDI プリンターを使用できない。

最新のインクジェットプリンターの機種は GDI ベース(レーザプリンターでは費用が主要因であるのに対し、ここでは主に性能の理由)であるが、より柔軟な傾向がある。多くが Mac に対応し、Linux コミュニティでは Linux 版ドライバーの対応をかなり改善した。一部(特にセイコーエプソン)ではより伝統的なエミュレーションを予備として提供することが多い。

一般的には安価なレーザプリンターは GDI デバイスであるが、多くのメーカーでは PCL や PostScript あるいはその両方の機能を持つモデルも製造している。GDI のみに対応するプリンターはどのメーカーにおいても最も安価なモデルとして位置づけられる。

## 詳細

### デバイスコンテキスト

デバイスコンテキスト (device context) は、描画する対象を抽象化した存在である。画面またはプリンターへ出力するテキストおよびイメージの属性を定義するために使われ、関連付けられたグラフィックスオブジェクトとそれに関連する属性の集合からなる。実際のコンテキストはGDIによって管理される。構造体へのハンドルであるデバイスコンテキストは出力を行う前に取得し、要素が書き込まれた後に解放する。大抵のGDIオブジェクトのように、デバイスコンテキストは直接データにアクセスできないという意味で隠蔽されているが、それを制御し、何かを描画し、情報を取得し、オブジェクトを変更するといったような様々な GDI 関数にデバイスコンテキストを渡すことができる。

デバイスコンテキストには次の種類がある。

- 画面
- プリンター
- メモリ
- 情報(インフォメーションコンテキスト)

このうち、情報は描画に用いることはできない情報取得専用のデバイスコンテキストである。

### グラフィックスオブジェクト

デバイスコンテキストに関連付けが可能なグラフィクスオブジェクトには次の種類がある。これらは、`SelectObject`関数や`SelectPalette`関数によってデバイスコンテキストに関連付けさせることが可能である。

- ビットマップ (HBITMAP)
- ブラシ (HBRUSH)
- フォント (HFONT)
- ペン (HPEN)
- リージョン (HRGN)
- パス (リージョンに変換可能)
- パレット (HPALETTE)

なおGDIオブジェクトの数は、1セッションで65,535個まで、そして1プロセスで10,000個までという上限が設けられている。

## GDI+

GDI+ は Windows XP で新しく登場したグラフィックスサブシステムである。Windows XP 以降のOSに標準搭載されているほか、Windows 98/NT 4.0 SP6 以降で追加インストールにより使用可能である 。

GDI+は高レベルの 2D グラフィック環境であり、アルファブレンド、グラデーション、アンチエイリアス、より複雑なラインパス管理、(GDI で特に欠けていた)JPEG や PNG のような新標準の画像形式の根本的な対応、2D 表示のパイプライン上のアフィン変換の合成に対する統合的な対応といった先進的な機能を追加している。これらの機能は Windows XP のユーザーインターフェイスの様々な箇所に使われており、このような基本的なグラフィックスレイヤーの表現能力拡張は、Flash や SVG といったベクターグラフィックスシステムの実装を大きく単純化する。

基本的にはネイティブ C++ 用のクラスライブラリ (DLL) のみが提供される形となっているが、.NET Framework の基本クラスライブラリでは `System.Drawing` 名前空間に GDI+ のマネージラッパーインターフェイスが用意されており、Windows Formsなどで標準的に使用されている。DelphiにおいてもGDI+のユニットが利用可能となっている。

なお、Vista で v1.1 となった。C++アプリケーションにおいてGDI+ 1.1の追加機能を使うためには、<gdiplus.h>をインクルードする前に`GDIPVER`を`0x0110`として定義し、さらにGdiPlus.dllのSide-by-Sideアセンブリバージョン1.1を使うようにマニフェストを指定しなければならない。

## Direct2D

Windows Vistaでは、ハードウェアによるGDIアクセラレーションが実行されず、GDI描画はすべてCPUで実行されることになる(ただしBitBltは除く)。また、GDI+では飛躍的に表現力や描画品質が向上しているが、内部で使用されているAPIはレガシーなGDIそのものであったりソフトウェア実装であったりするため、描画速度は当然犠牲になる。これらを補完する形でWindows 7とともに登場したのが Direct2D および DirectWrite である。Direct2D/DirectWrite は、GDI+ のような先進的な機能を Direct3D 10.1 上に構築した COM ベースの高レベル API で、GDI/GDI+ で問題となっていた描画速度性能を、Direct3D によるハードウェアアクセラレーションを活用することで大幅に改善することが可能となる。さらに、Direct2DはDirect3D上に構築されているため、DWMの使用有無にかかわらずハードウェアアクセラレートされる。また、DirectWriteはGDI+に欠けていた、OpenTypeフォントへの対応や垂直方向へのClearTypeアンチエイリアスといった機能を備えている。

なお、GDI+での強化点であった各種形式の画像ファイルの読み込みや書き出しといった機能に関しては、Direct2Dコンポーネントは直接サポートせず、代わりにWIC(Windows Imaging Component)が担うことになる。

Direct2DにはベースとなっているDirect3Dとの連携機構が確保されており、Direct2D 1.0 APIを使用してDXGIインターフェイス経由でDirect3D 10.xテクスチャに直接書き込んだり、またDirect2D 1.1 APIを使用してDirect3D 11.xテクスチャに直接書き込んだりすることが可能となっている。

Windows 7 および Windows Vista SP2 + Platform Update 以降に提供されている Direct2D 1.0 では、印刷機能(印刷機器への出力機能)に直接対応しないため、印刷時には GDI/GDI+ あるいは XPS ドキュメント API(XPS 作成やそれを用いての印刷などに対応する API)を使用する必要がある。しかし、Windows 8 および Windows 7 SP1 + Platform Update 以降に提供されている Direct2D 1.1 以降であれば、メタデータの出力機能などが追加実装されており、描画内容をプリンターデバイスに出力して印刷することも可能である。