グラフィックス
最終更新:
atachi
WPF時代のグラフィックス
WPFではボタンやツリービューなどのコントロールの外観を描画する方法に新しい方式を取り入れています。
これまでは、グラフィックスとしてピクセルの描画を行っていましたが、WPFではこれらがパスなどを用いたドローイング方式となりました。
ビジュアルオブジェクト
WPFでは描画する領域をビジュアルオブジェクトと呼び、ビジュアルオブジェクトに対し描画関数により図形の描画を行います。
すべてのコントロールは1つから複数のビジュアルオブジェクトの組み合わせで描画されており、コントロール自身もビジュアルオブジェクトです。
ビジュアルオブジェクトは親子関係を構築することができます。
コントロール自身もビジュアルオブジェクトなので、ボタンの文字が表示される場所に画像を表示したり、ツリービューコントロールを表示することもできます。

予め用意されているWPFで使用できるコントロールはFrameworkElementのサブクラスです。
カスタムコントロール
自分で独自のコントロールを作成する場合、ソースコードで定義するにはFrameworkElementのサブクラスとして作成します。
WPFでの画像の扱い
WPFではBitmapSourceのサブクラスを主に扱います。このクラスはWPFのコントロールやスタイルと共に使いやすいように様々なプロパティやインターフェースを持ったものです。
GDI+ではImageクラスを主に扱います。Imageクラスは画像そのものをデータとしてクラスにカプセル化したものでこのクラス自体は画像への操作などは行うことができません。
グラフィックス関連のクラス構成
Object | ||||||||
└ | DispathcerObject | |||||||
└ | DependencyObject | |||||||
└ | Freezable | |||||||
└ | Animatable | |||||||
└ | ImageSource | |||||||
├ | BitmapSource | |||||||
│ | ├ | BitmapFrame | MSDN | |||||
│ | └ | BitmapImage | ||||||
└ | DrawingImage |
レンダリング
DrawingVisualは図形などを描画するためのコンテキストや描画した図形情報を格納しています。
実際にDrawingVisualに図形を描画するにはDrawingVisualからDrawingContextを取得します。
DrawingVisual dv = new DrawingVisual();
using(DrawingContext dc = dv.RenderOpen()){
dc.DrawEllipse(Brushes.Red,null,new Point(0,0), 1,1);
}
シェイプ
System.Windows.Shapes名前空間に属した形を描画するためのクラス群です。
シェイプはベクターグラフィックスなので、解像度の変更にもスムーズに適切な解像度で描画されます。
Rectangle | 矩形 |
Ellipse | 楕円 |
Line | 直線 |
Path | 曲線 |
Polygon | 多角形 |
Polyline | 閉じていない多角形 |
PolygonとPolylineは似ていますが、複数の直線で構成された図形がとじているか閉じていないかで異なります。
また、Pathは連続した直線・曲線となります。
ブラシ
// 正方形の矩形
Rectangle rect = new Rectangle();
rect.Width = 75;
rect.Height = 75;
// 矩形を単色で塗りつぶす
SolidColorBrush myBrush = new SolidColorBrush(Colors.Red);
rect.Fill = myBrush;
ブラシの種類
SolidColorBrush | 単色塗りつぶし |
LinearGradientBrush | 線形グラデーション塗りつぶし |
RadialGradientBrush | 円形グラデーション塗りつぶし |
ImageBrush | 画像による塗りつぶし(拡大・縮小・タイル) |
DrawingBrush | |
VisualBrush |
ジオメトリ
ジオメトリはドロー系ソフトの「パス」と考えるとわかりやすい。(Adobe Illustratorなど)
ジオメトリによって描画した図形は、拡大・縮小を行う際にその都度、座標を変えて再描画する必要がない(自動的に計算される)
また、イージングなどのアニメーションが可能で、始点と終点の座標を与えれば中割の描画は自動的に計算され表示される。
このような特徴を持ったジオメトリは、Geometry クラスを基点としたクラスツリーをとる。
図形の描画に関しては、Shapeと同じものが用意されている。
// Create a figure that describes a
// line from (10,20) to (100,130).
PathFigure myPathFigure = new PathFigure();
myPathFigure.StartPoint = new Point(10,20);
myPathFigure.Segments.Add(
new LineSegment(new Point(100,130),
true /* IsStroked */ ));
/// Create a PathGeometry to contain the figure.
PathGeometry myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(myPathFigure);
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;
canvas1.Children.Add(myPath);
ジオメトリの描画
ジオメトリをVisualObjectに描画するにはUIElementクラスである必要があります。
UIElementのサブクラスであるPathクラスを使用してジオメトリをCanvasに描画するのが一般的です。
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry; // ジオメトリを設定
canvas1.Children.Add(myPath); // XAMLなどで定義したCanvas
レンダリング
画像のレンダリングには、作成する画像の目的によって2種類の方法があります。
1つ目がユーザーインターフェース用の画像の作成です。ユーザーインターフェースではどのような環境でも表示される事が望まれるため、表示環境(DPIなど)に影響されにくいような描画システムを必要とします。
2つ目がビットマップなどの画像を作成するためのレンダリングです。
こちらは主にマルチメディアのための画像です。
それぞれレンダリングするためのクラスが異なります。
前者は、System.Windows.Media名前空間に属しています。
後者は、System.Drawing名前空間に属しており、GDI+とよばれる描画ライブラリのラッパーです。
UIのレンダリング
ボタンなどのフォームコントロールを表示するための画像はDrawingVisualクラスを使用します。
このクラスは画像作成のためのコンテキストを持っており、プログラムによって図形を描画した後、ビットマップとして画像を取得できます。
このコンテキストは画像や図形を描画するためのメソッドを備えているため、簡単に図形を作成することができます。
出来上がるのは1枚のビットマップであるため、マウスイベントなどの処理はできません。
DrawingVisual drawingVisual = new DrawingVisual();
// 描画用のコンテキストを取得
DrawingContext drawingContext = drawingVisual.RenderOpen();
// 矩形を描画
Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80));
drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);
// コンテキストを閉じる
drawingContext.Close();
次のようにすればビットマップとして描画した画像を取り出せます。
RenderTargetBitmap bmp = new RenderTargetBitmap(180, 180, 120, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
ビットマップのレンダリング
Bitmap myBitmap = new Bitmap(100, 100); // レンダリングするためのキャンバスを作成します。
// この例では「100×100」の画像を作成します。
Graphics g = Graphics.FromImage(myBitmap); // 描画用コンテキストの作成