ビットマップ画像、ベクタ・グラフィックス、3Dグラフィックスなどを扱うWPFのUI要素と、ブラシ、変形、ビットマップ効果などのグラフィックス関連機能を解説。
powered by Insider.NET
第1回で説明したように、WPFでは、コントロール、メディア、文書など、さまざまなUI要素を統一的に扱うことができる。メディアだけを見ても、ビットマップ画像、ベクタ・グラフィックス、3Dグラフィックスなど、さまざまなメディアを対象としている。
今回は、このようなメディア関連のUI要素と、ブラシ、変形、ビットマップ効果などグラフィックスに関連する項目について説明していく。
WPFでは、以下のようなメディアを統一的に取り扱える。
各メディアの話に入る前に、1つ補足をしておこう。
●補足:FrameworkElement派生クラスとDrawing派生クラス
WPFには、FrameworkElementクラス(System.Windows名前空間)から派生するものとDrawingクラス(System.Windows.Media名前空間)から派生するものの2系統のクラス群が存在する。
FrameworkElementクラスは、UI要素として利用する分には非常に便利なレイアウトやスタイルなどの機能を有するが、これらの機能は単に描画を行いたいだけの場合には機能過多で、性能上の問題となることもある。そこで、レイアウトなどの機能を持たず、描画機能だけを提供する軽量にベクタ・グラフィックスを描画するクラスとして提供されているのがDrawingクラスである。
Table 1に示すように、3Dグラフィックス以外は、FrameworkElementクラスから派生するものとほぼ1対1に、Drawingクラスから派生するクラスが存在する。
FrameworkElement | Drawing | |
---|---|---|
幾何学図形 | Shape | GeometryDrawing |
画像 | Image | ImageDrawing |
動画/音声 | MediaElement | VideoDrawing |
グリフ | Glyphs | GlyphRunDrawing |
3D | Viewport3D | (なし) |
Table 1: メディア関連のFrawemorkElement派生クラスとDrawing派生クラス |
直接利用する機会が多いのはFrameworkElementから派生する側のクラス群だろう。一方で、Drawingクラスは以下のクラスで利用する。
また、DrawingクラスはFreezableクラス(第7回のコラム参照)から派生しているため、固定化(frozen)してあればマルチスレッドで利用可能である。グラフィックス関係のオブジェクトを複数のスレッドから参照するなら、Drawingクラスを使う必要がある。
差し当たって、「Drawingクラスから派生するクラス群は高速な描画が必要な際に使う」とだけ覚えておけばいいだろう。以下の各メディアの解説では、利用頻度の高いFrameworkElementクラスから派生するUI要素についてのみ説明する。
●メディア:幾何学図形(=ベクタ・グラフィックス)
Shapeクラス(System.Windows.Shapes名前空間)から派生するUI要素によって、四角形(=矩形)やだ円などの幾何学図形を描画できる(以下、これらのUI要素を総称して「Shape要素」と呼ぶ)。WPFではこれらの幾何学図形はベクタ・グラフィックスとして描画されるため、Figure 1に示すように、拡大しても荒くならない。
Shape要素には以下のようなUI要素が存在する(いずれもSystem.Windows.Shapes名前空間)。
注意点として、<Rectangle>要素や<Ellipse>要素では、斜め向きの図形は作れない(辺や長軸/短軸がx軸/y軸と平行なものだけを作れる)。斜め向きにしたければ、さらに、後述する変形(=RenderTransformプロパティなど)を用いて回転処理を掛ける。
○塗りつぶしと枠線
すべてのShape要素に共通して、塗りつぶしと枠線の描画方法を設定できる。Fillプロパティによって塗りつぶしに使うブラシを、Strokeプロパティによって枠線に使うブラシを指定する。また、StrokeThicknessプロパティのように、Strokeから始まるいくつかのプロパティを用いて枠線の表示方法を変更できる。枠線の変更の例をMovie 1に示す。
○<Polyline>要素/<Polygon>要素の塗りつぶし判定
<Polyline>要素および<Polygon>要素では、線の引き方によっては図形の内側/外側(=塗りつぶすべき領域かどうか)の判定に迷う場合がある。以下のようなXAMLコードによって描ける五芒星(ごぼうせい)がその例の1つとなる。
<Polygon Points="100 0 158 180 4 69 195 69 41 180" Stroke="Black" Fill="LightBlue" />
このような場合に、<Polyline>要素および<Polygon>要素には、FillRuleというプロパティがあり、Figure 2に示すような判定方法が存在する。ある点を始点として半直線を伸ばしたときに、図形の枠線とその半直線が何回交わっているかによって図形の内側/外側を判定する。FillRuleプロパティが「EvenOdd」の場合には交点が奇数のときだけを、「NoneZero」の場合には0回以上のときを内側と見なす。
○<Path>要素とジオメトリ
<Path>要素の場合、任意形状の図形を描けるが、この形状に関する情報をWPFでは「ジオメトリ」と呼び、Geometryクラス(System.Windows.Media名前空間)によって表現する(詳細は後述)。
<Path>要素では、Dataプロパティにジオメトリを指定する。XAMLコード中でジオメトリを簡潔に記述するためのパス・マークアップ構文と呼ばれるミニ言語があり、多くの場合、このミニ言語を利用して<Path>要素のDataプロパティを記述する(パス・マークアップ構文に関しても後述)。
例えば、以下のようなXAMLコードによって、Figure 3に示すような図形を描くことができる。
<Path Stroke="Black" Fill="Gray"
Data="M 10,100 C 10,300 300,-200 300,100" />
●メディア:画像
画像の表示には<Image>要素(System.Windows.Controls)を利用する。画像自体はImageSourceクラス(System.Windows.Media名前空間)のオブジェクトで表現され、これを<Image>要素のSourceプロパティに与えることでさまざまな画像を画面上に表示する。
ImageSourceクラスから派生するクラスには、大きく分けると以下の2つがある。
また、D3DImageクラス(System.Windows.Interop名前空間)によって、Direct3DのサーフェスをWPFウィンドウ中に埋め込むこともできる。
○ビットマップ画像
BitmapSourceクラスから派生するクラスがいくつかあり(いずれもSystem.Windows.Media.Imaging名前空間)、用途によって使い分ける。
また、BitmapSourceクラスのCreate静的メソッドを用いて、バイト配列から画像を生成できる。
○画像ファイルの読み込み
XAMLコード中では、以下のように、<Image>要素のSourceプロパティに画像のパスを直接指定できる。
<Image Source="logo.png" />
絶対パスを用いて画像の読み込み元を詳細に指定するには、Pack URIという記法を用いる。一方、上記の例のように相対パスを用いた場合には、Figure 4に示すように、アセンブリ・リソース(連載第4回参照)から画像が読み込まれる。
○扱える画像の形式
WPFでは標準で、ビットマップ(.bmp)、アイコン(.ico)、JPEG、PNG、GIF、TIFF、および、HD Photo(旧称Windows Media Photo。現在はJPEG XRとしてJPEG規格の一部となっている)形式に対応していて、これらの形式なら、前述の<Image>要素のSourceプロパティに対するパス指定で読み込むことができる。
また、BitmapEncoderクラスおよびBitmapDecoderクラスや、それらから派生する各種XxxBitmapEncoder/XxxBitmapDecoderクラス(いずれもSystem.Windows.Media.Imaging名前空間)を用いることで、明示的に画像の読み込み/保存が行える。例えば、JPEG形式で画像を保存したければ、JpegBitmapEncoder/JpegBitmapDecoderクラスを利用する。
●メディア:動画/音声
<MediaElement>要素(System.Windows.Controls名前空間)を用いて動画や音声などのメディアを再生できる。WPFの<MediaElement>要素は、Windows Media Player 10でサポートされているすべての種類のメディアをサポートする。
<MediaElement>要素を使ったメディア再生は非常に簡単で、以下のように、Sourceプロパティに再生したい動画や音声などのメディアのURIを指定するだけでよい。
<MediaElement Source="demo.wmv" />
ただし、相対URIを指定した場合の挙動が<Image>要素のSourceプロパティとは異なる点に注意が必要である。<MediaElement>要素のSourceプロパティに相対URIを指定した場合、(アセンブリ・リソースではなく)アプリケーションの実行可能形式ファイル(=.EXEファイル)からの相対パスで外部ファイルを参照する。
●メディア:グリフ
<Glyphs>要素(System.Windows.Documents名前空間)によって、低水準な文字描画を行うことができる。<TextBlock>要素などと比べて記述が煩雑になる半面、細やかな描画制御が行える。日本語環境では、縦書きの文字描画を正しく行うために<Glyphs>要素を用いることが多い。
●メディア:3Dグラフィックス
<Viewport3D>要素(System.Windows.Controls名前空間)によって、3DグラフィックスをWPFウィンドウ中に埋め込むことができる。
さまざまなUI要素を統一的に扱えるのがWPFの強みで、Movie 2に示すように、3Dグラフィックスの中にコントロールを描画することも可能である。
ただし、3Dグラフィックスといっても、(ゲーム用の開発基盤である)Direct3DやXNAの置き換えを狙ったものではないので注意が必要である。
まず、ツールの問題がある。WPF自身は3Dグラフィックスを表示する能力を持っているが、Visual StudioやExpression Blendなどのツールが3D CAD的な編集能力を持っているわけではない。一般的な3D CADツール(例:AutoCAD)や3D CGツール(例:3ds Max)で編集した3DモデルをXAML形式にエクスポートしたり変換を掛けたりしてWPFに取り込む必要がある。
また、WPFは、イベント駆動が前提、すなわち、何かイベントがあるまで画面を再描画しないという前提の下でパフォーマンスが最適化されている。ゲームのように、高頻度で再描画を行うようなものには適していない。
以上、メディア関連要素について説明した。次のページでは、ブラシ、変形、ビットマップ効果などグラフィックスに関連する項目について説明する。
Copyright© Digital Advantage Corp. All Rights Reserved.