WPF での図形と基本描画の概要
更新 : 2007 年 11 月
ここでは、Shape オブジェクトを使用した描画方法の概要を示します。Shape は、画面に図形を描画できるようにする UIElement の一種です。Shape オブジェクトは UI 要素であるため、Panel 要素およびほとんどのコントロール内で使用できます。
Windows Presentation Foundation (WPF) には、グラフィックス サービスやレンダリング サービスへのアクセスのレイヤがいくつか用意されています。最上位レイヤにある Shape オブジェクトは使いやすく、Windows Presentation Foundation (WPF) イベント システムでのレイアウトや参加などのさまざまな役立つ機能を提供します。
このトピックには次のセクションが含まれています。
- 図形オブジェクト
- パスとジオメトリの使用
- 図形の塗りつぶし
- 伸縮可能な図形
- 図形の変換
- 関連トピック
図形オブジェクト
WPF には、すぐに使用できるさまざまな Shape オブジェクトが用意されています。すべての図形オブジェクトは Shape クラスから継承されます。使用可能な図形オブジェクトには、Ellipse、Line、Path、Polygon、Polyline、Rectangle などがあります。Shape オブジェクトは、次の共通プロパティを共有します。
Stroke : 図形のアウトラインをどのように塗りつぶすかを示します。
StrokeThickness : 図形のアウトラインの太さを示します。
Fill : 図形の内部をどのように塗りつぶすかを示します。
デバイス非依存ピクセル単位で計測される座標と頂点を指定するデータ プロパティ。
図形オブジェクトは UIElement から派生するため、パネルおよびほとんどのコントロール内で使用できます。Canvas パネルは子オブジェクトの絶対配置をサポートするため、複雑な描画の作成に特に適しています。
Line クラスを使用すると、2 つの点の間の直線を描画できます。直線の座標およびストローク プロパティを指定するいくつかの方法を次の例に示します。
<Canvas Height="300" Width="300">
<!-- Draws a diagonal line from (10,10) to (50,50). -->
<Line
X1="10" Y1="10"
X2="50" Y2="50"
Stroke="Black"
StrokeThickness="4" />
<!-- Draws a diagonal line from (10,10) to (50,50)
and moves it 100 pixels to the right. -->
<Line
X1="10" Y1="10"
X2="50" Y2="50"
StrokeThickness="4"
Canvas.Left="100">
<Line.Stroke>
<RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
<RadialGradientBrush.GradientStops>
<GradientStop Color="Red" Offset="0" />
<GradientStop Color="Blue" Offset="0.25" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</Line.Stroke>
</Line>
<!-- Draws a horizontal line from (10,60) to (150,60). -->
<Line
X1="10" Y1="60"
X2="150" Y2="60"
Stroke="Black"
StrokeThickness="4"/>
</Canvas>
' Add a Line Element
Dim myLine As New Line()
myLine.Stroke = Brushes.LightSteelBlue
myLine.X1 = 1
myLine.X2 = 50
myLine.Y1 = 1
myLine.Y2 = 50
myLine.HorizontalAlignment = HorizontalAlignment.Left
myLine.VerticalAlignment = VerticalAlignment.Center
myLine.StrokeThickness = 2
myGrid.Children.Add(myLine)
// Add a Line Element
myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myLine.X1 = 1;
myLine.X2 = 50;
myLine.Y1 = 1;
myLine.Y2 = 50;
myLine.HorizontalAlignment = HorizontalAlignment.Left;
myLine.VerticalAlignment = VerticalAlignment.Center;
myLine.StrokeThickness = 2;
myGrid.Children.Add(myLine);
レンダリングされた Line を次の図に示します。
Line クラスは Fill プロパティを提供しますが、Line には領域がないため、そのプロパティを設定しても無効です。
もう 1 つの一般的な図形は Ellipse です。Ellipse は、図形の Width および Height プロパティを定義して作成します。円を描画するには、Width および Height の値が等しい Ellipse を指定します。
<Ellipse
Fill="Yellow"
Height="100"
Width="200"
StrokeThickness="2"
Stroke="Black"/>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace SDKSample
{
public partial class SetBackgroundColorOfShapeExample : Page
{
public SetBackgroundColorOfShapeExample()
{
// Create a StackPanel to contain the shape.
StackPanel myStackPanel = new StackPanel();
// Create a red Ellipse.
Ellipse myEllipse = new Ellipse();
// Create a SolidColorBrush with a red color to fill the
// Ellipse with.
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
// Describes the brush's color using RGB values.
// Each value has a range of 0-255.
mySolidColorBrush.Color = Color.FromArgb(255, 255, 0, 0);
myEllipse.Fill = mySolidColorBrush;
// Set the width and height of the Ellipse.
myEllipse.Width = 100;
myEllipse.Height = 100;
// Add the Ellipse to the StackPanel.
myStackPanel.Children.Add(myEllipse);
this.Content = myStackPanel;
}
}
}
レンダリングされた Ellipse の例を次の図に示します。
パスとジオメトリの使用
Path クラスを使用すると、曲線および複雑な図形を描画できます。これらの曲線および図形は、Geometry オブジェクトを使用して表現されます。Path を使用するには、Geometry を作成し、それを使用して Path オブジェクトの Data プロパティを設定します。
さまざまな Geometry オブジェクトが用意されています。LineGeometry、RectangleGeometry、および EllipseGeometry クラスは、比較的単純な図形を表現します。より複雑な図形または曲線を作成するには、PathGeometry を使用します。
PathGeometry と PathSegment
PathGeometry オブジェクトは 1 つ以上の PathFigure オブジェクトで構成され、各 PathFigure は異なる "形状" または図形を表します。各 PathFigure 自体は 1 つ以上の PathSegment オブジェクトで構成されており、このオブジェクトは形状または図形の接続されている部分を表します。セグメントの種類には、LineSegment、BezierSegment、ArcSegment などがあります。
次の例では、Path を使用して 2 次ベジエ曲線を描画します。
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="10,100">
<PathFigure.Segments>
<PathSegmentCollection>
<QuadraticBezierSegment Point1="200,200" Point2="300,100" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
レンダリングされた図形を次の図に示します。
PathGeometry およびその他の Geometry クラスの詳細については、「ジオメトリの概要」を参照してください。
省略された XAML 構文
Extensible Application Markup Language (XAML) では、省略された特殊な構文を使用して Path を記述することもできます。次の例では、省略された構文を使用して複雑な図形を描画します。
<Path Stroke="DarkGoldenRod" StrokeThickness="3"
Data="M 100,200 C 100,25 400,350 400,175 H 280" />
レンダリングされた Path を次の図に示します。
Data 属性文字列は、M で示される "moveto" コマンドで始まります。このコマンドは、Canvas の座標系のパスの始点を設定します。Path データ パラメータでは大文字と小文字が区別されます。大文字の M は、現在の新しい点の絶対位置を示します。小文字の m は、相対座標を示します。最初のセグメントは、2 つの制御点 (100,25) と (400,350) を使用して描画される、始点が (100,200) で終点が (400,175) の 3 次ベジエ曲線です。このセグメントは、Data 属性文字列の C コマンドで示されます。ここでも、大文字の C は絶対パスを示し、小文字の c は相対パスを示します。
2 番目のセグメントは、絶対水平 "lineto" コマンド H で始まります。このコマンドは、前のサブパスの終点 (400,175) から新しい終点 (280,175) まで描画される直線を指定します。水平 "lineto" コマンドであるため、指定される値は x 座標です。
パスの構文全体については、Data のリファレンスと「方法 : PathGeometry を使用して図形を作成する」を参照してください。
図形の塗りつぶし
Brush オブジェクトは、図形の Stroke および Fill を塗りつぶす場合に使用します。次の例では、Ellipse のストロークおよび塗りつぶしを指定します。ブラシ プロパティの有効な入力は、キーワードまたは 16 進数のカラー値のいずれかです。使用可能なカラー キーワードの詳細については、System.Windows.Media 名前空間の Colors クラスのプロパティを参照してください。
<Canvas Background="LightGray">
<Ellipse
Canvas.Top="50"
Canvas.Left="50"
Fill="#FFFFFF00"
Height="75"
Width="75"
StrokeThickness="5"
Stroke="#FF0000FF"/>
</Canvas>
レンダリングされた Ellipse を次の図に示します。
このほか、プロパティ要素構文を使用して SolidColorBrush オブジェクトを明示的に作成し、純色で図形を塗りつぶすこともできます。
<!-- This polygon shape uses pre-defined color values for its Stroke and
Fill properties.
The SolidColorBrush's Opacity property affects the fill color in
this case by making it slightly transparent (opacity of 0.4) so
that it blends with any underlying color. -->
<Polygon
Points="300,200 400,125 400,275 300,200"
Stroke="Purple"
StrokeThickness="2">
<Polygon.Fill>
<SolidColorBrush Color="Blue" Opacity="0.4"/>
</Polygon.Fill>
</Polygon>
レンダリングされた図形を次の図に示します。
図形のストロークまたは塗りつぶしをグラデーション、イメージ、パターンなどで塗りつぶすこともできます。詳細については、「純色およびグラデーションによる塗りつぶしの概要」を参照してください。
伸縮可能な図形
Line、Path、Polygon、Polyline、および Rectangle クラスには、すべて Stretch プロパティがあります。このプロパティは、Shape オブジェクトのコンテンツ (描画される図形) をどのように引き伸ばして Shape オブジェクトのレイアウト空間を塗りつぶすかを決定します。Shape オブジェクトのレイアウト空間は、明示的な Width および Height 設定または HorizontalAlignment および VerticalAlignment 設定のために、レイアウト システムによって Shape に割り当てられるスペースです。Windows Presentation Foundation のレイアウトの詳細については、「レイアウト システム」を参照してください。
Stretch プロパティには、次のいずれかの値を指定します。
Fill : Shape オブジェクトのコンテンツは、レイアウト空間を塗りつぶすように引き伸ばされます。縦横比は維持されません。
Uniform : Shape オブジェクトのコンテンツは、元の縦横比を維持しながら、レイアウト空間を塗りつぶすように可能な限り引き伸ばされます。
UniformToFill : Shape オブジェクトのコンテンツは、元の縦横比を維持しながら、レイアウト空間を完全に塗りつぶすように引き伸ばされます。
Shape オブジェクトのコンテンツを引き伸ばすとき、Shape オブジェクトのアウトラインは、引き伸ばされた後に塗りつぶされます。
次の例では、Polygon を使用して、頂点が (0,0)、(0,1)、および (1,1) の非常に小さい三角形を描画します。Polygon オブジェクトの Width および Height は 100 に設定され、その Stretch プロパティは Fill に設定されます。その結果、Polygon オブジェクトのコンテンツ (三角形) は、より大きい空間を塗りつぶすように引き伸ばされます。
...
<Polygon
Points="0,0 0,1 1,1"
Fill="Blue"
Width="100"
Height="100"
Stretch="Fill"
Stroke="Black"
StrokeThickness="2" />
...
...
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(new Point(0,0));
myPointCollection.Add(new Point(0,1));
myPointCollection.Add(new Point(1,1));
Polygon myPolygon = new Polygon();
myPolygon.Points = myPointCollection;
myPolygon.Fill = Brushes.Blue;
myPolygon.Width = 100;
myPolygon.Height = 100;
myPolygon.Stretch = Stretch.Fill;
myPolygon.Stroke = Brushes.Black;
myPolygon.StrokeThickness = 2;
...
図形の変換
Transform クラスは、2 次元の平面で図形を変換する手段を提供します。変換には、回転 (RotateTransform)、スケーリング (ScaleTransform)、傾斜 (SkewTransform)、および平行移動 (TranslateTransform) などのさまざまな種類があります。
図形に適用される一般的な変換は回転です。図形を回転するには、RotateTransform を作成し、その Angle を指定します。Angle が 45 の場合は要素が時計回りに 45 度回転し、90 では要素が時計回りに 90 度回転します。要素の回転の中心点を設定するには、CenterX と CenterY のプロパティを設定します。これらのプロパティ値は、変換する要素の座標空間で表します。CenterX および CenterY の既定値は 0 です。最後に、要素に RotateTransform を適用します。変換がレイアウトに影響しないようにする場合は、図形の RenderTransform プロパティを設定します。
次の例では、RotateTransform を使用して、図形をその左上隅 (0,0) を中心に 45 度回転しています。
<!-- Rotates the Polyline 45 degrees about the point (0,0). -->
<Polyline Points="25,25 0,50 25,75 50,50 25,25 25,0"
Stroke="Blue" StrokeThickness="10"
Canvas.Left="75" Canvas.Top="50">
<Polyline.RenderTransform>
<RotateTransform CenterX="0" CenterY="0" Angle="45" />
</Polyline.RenderTransform>
</Polyline>
次の例では、別の図形を 45 度回転していますが、この場合は (25,50) が回転の中心です。
<!-- Rotates the Polyline 45 degrees about its center. -->
<Polyline
Points="25,25 0,50 25,75 50,50 25,25 25,0"
Stroke="Blue" StrokeThickness="10"
Canvas.Left="75" Canvas.Top="50"
RenderTransformOrigin="0.5,0.5">
<Polyline.RenderTransform>
<RotateTransform Angle="45" />
</Polyline.RenderTransform>
</Polyline>
上記 2 つの変換を適用すると、結果は次の図のようになります。
前の例では、単一の変換を各図形オブジェクトに適用しました。1 つの図形 (またはその他の UI 要素) に複数の変換を適用するには、TransformGroup を使用します。
参照
概念
パフォーマンスの最適化 : 2D グラフィックスとイメージング