Drawing オブジェクトの概要

このトピックでは、Drawing オブジェクトについて紹介し、それを使用して図形、ビットマップ、テキスト、メディアを効率的に描画する方法を説明します。 クリップアートを作成するとき、DrawingBrush で描画するとき、または Visual オブジェクトを使用するときは、Drawing オブジェクトを使用します。

Drawing オブジェクトとは

Drawing オブジェクトでは、シェイプ、ビットマップ、ビデオ、テキスト行などの表示可能なコンテンツを記述します。 さまざまな種類の描画で、さまざまな種類のコンテンツを記述します。 次の一覧に、さまざまな種類の描画オブジェクトを示します。

  • GeometryDrawing - 図形を描画します。

  • ImageDrawing - イメージを描画します。

  • GlyphRunDrawing - テキストを描画します。

  • VideoDrawing - オーディオまたはビデオのファイルを再生します。

  • DrawingGroup - その他の描画を行います。 他の描画を 1 つの複合描画に結合するには、描画グループを使用します。

Drawing オブジェクトは汎用的です。Drawing オブジェクトには多くの使用法があります。

  • DrawingImage および Image コントロールを使用すると、イメージとして表示できます。

  • DrawingBrush と共に使用すると、PageBackground などのオブジェクトを描画できます。

  • DrawingVisual の外観の記述に使用できます。

  • Visual のコンテンツの列挙に使用できます。

WPF には、図形、ビットマップ、テキスト、メディアを描画できる他の型のオブジェクトが用意されています。 たとえば、Shape オブジェクトを使用して図形を描画することもできます。MediaElement コントロールはアプリケーションにビデオを追加する別の方法を提供します。 それでは、どのようなときに Drawing オブジェクトを使用する必要があるのでしょうか。 フレームワーク レベルの機能を犠牲にしてパフォーマンス上の利点を得ることができる場合、または Freezable の機能が必要な場合です。 Drawing オブジェクトはレイアウト、入力、フォーカスをサポートしていないため、背景の記述、クリップアート、Visual オブジェクトでの低レベルの描画に理想的なパフォーマンス上の利点を提供します。

Drawing オブジェクトは、Freezable オブジェクトの一種であるため、いくつかの特殊な機能があります。たとえば、リソースとしての宣言、複数オブジェクトでの共有、読み取り専用にすることによるパフォーマンスの向上、複製、スレッド セーフ化などです。 Freezable オブジェクトで提供されるさまざまな機能について詳しくは、「Freezable オブジェクトの概要」をご覧ください。

図形の描画

図形を描画するには、GeometryDrawing を使用します。 ジオメトリ描画の Geometry プロパティは描画する図形を記述し、Brush プロパティは図形の内部の描画方法を記述し、Pen プロパティはアウトラインの描画方法を記述します。

次の例では、GeometryDrawing を使用して図形を描画します。 この図形は 1 つの GeometryGroup オブジェクトと 2 つの EllipseGeometry オブジェクトによって記述されます。 図形の内側は LinearGradientBrush で塗りつぶされ、その枠線は BlackPen で描画されます。

この例では、次の GeometryDrawing が作成されます。

A GeometryDrawing of two ellipses
GeometryDrawing

//
// Create the Geometry to draw.
//
GeometryGroup ellipses = new GeometryGroup();
ellipses.Children.Add(
    new EllipseGeometry(new Point(50,50), 45, 20)
    );
ellipses.Children.Add(
    new EllipseGeometry(new Point(50, 50), 20, 45)
    );

//
// Create a GeometryDrawing.
//
GeometryDrawing aGeometryDrawing = new GeometryDrawing();
aGeometryDrawing.Geometry = ellipses;

// Paint the drawing with a gradient.
aGeometryDrawing.Brush =
    new LinearGradientBrush(
        Colors.Blue,
        Color.FromRgb(204,204,255),
        new Point(0,0),
        new Point(1,1));

// Outline the drawing with a solid color.
aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);
<GeometryDrawing>
  <GeometryDrawing.Geometry>

    <!-- Create a composite shape. -->
    <GeometryGroup>
      <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
      <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
    </GeometryGroup>
  </GeometryDrawing.Geometry>
  <GeometryDrawing.Brush>

    <!-- Paint the drawing with a gradient. -->
    <LinearGradientBrush>
      <GradientStop Offset="0.0" Color="Blue" />
      <GradientStop Offset="1.0" Color="#CCCCFF" />
    </LinearGradientBrush>
  </GeometryDrawing.Brush>
  <GeometryDrawing.Pen>

    <!-- Outline the drawing with a solid color. -->
    <Pen Thickness="10" Brush="Black" />
  </GeometryDrawing.Pen>
</GeometryDrawing>

完全な例については、「GeometryDrawing を作成する」をご覧ください。

PathGeometry などの他の Geometry クラスを使用すると、曲線や円弧を作成することでさらに複雑な図形を作成できます。 Geometry オブジェクトの詳細については、「ジオメトリの概要」をご覧ください。

Drawing オブジェクトを使用しないで図形を描画する他の方法について詳しくは、「WPF での図形と基本描画の概要」をご覧ください。

イメージの描画

イメージを描画するには、ImageDrawing を使用します。 ImageDrawing オブジェクトの ImageSource プロパティは描画するイメージを記述し、Rect プロパティはイメージが描画される領域を定義します。

次の例では、(75,75) に存在する 100 x 100 ピクセルの四角形にイメージを描画します。 次の図は、この例で作成した ImageDrawing を示しています。 グレーの境界は、ImageDrawing の範囲を示すために追加したものです。

A 100 by 100 ImageDrawing drawn at (75,75)
100×100 の ImageDrawing

// Create a 100 by 100 image with an upper-left point of (75,75).
ImageDrawing bigKiwi = new ImageDrawing();
bigKiwi.Rect = new Rect(75, 75, 100, 100);
bigKiwi.ImageSource = new BitmapImage(
    new Uri(@"sampleImages\kiwi.png", UriKind.Relative));
<!-- The Rect property specifies that the image only fill a 100 by 100
     rectangular area. -->
<ImageDrawing Rect="75,75,100,100" ImageSource="sampleImages\kiwi.png"/>

イメージについて詳しくは、「イメージングの概要」をご覧ください。

メディアの再生 (コードのみ)

注意

Extensible Application Markup Language (XAML) で VideoDrawing を宣言することはできますが、メディアの読み込みと再生ができるのはコードを使用する場合のみです。 Extensible Application Markup Language (XAML) でビデオを再生するには、代わりに MediaElement を使用します。

オーディオ ファイルまたはビデオ ファイルを再生するには、VideoDrawingMediaPlayer を使用します。 メディアを読み込んで再生するには、2 つの方法があります。 1 つ目の方法は、MediaPlayerVideoDrawing を単独で使用することです。2 つ目の方法は、MediaPlayerVideoDrawing で使用する独自の MediaTimeline を作成することです。

注意

アプリケーションでメディアを配布するときは、イメージのようにプロジェクト リソースとしてメディア ファイルを使うことはできません。 プロジェクト ファイルで、メディアの種類を Content に設定し、CopyToOutputDirectoryPreserveNewest または Always に設定する必要があります。

独自の MediaTimeline を作成しないでメディアを再生するには、次の手順を実行します。

  1. MediaPlayer オブジェクトを作成します。

    MediaPlayer player = new MediaPlayer();
    
  2. Open メソッドを使用して、メディア ファイルを読み込みます。

    player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
    
  3. VideoDrawing を作成します。

    VideoDrawing aVideoDrawing = new VideoDrawing();
    
  4. VideoDrawingRect プロパティを設定することで、メディアを描画するサイズと位置を指定します。

    aVideoDrawing.Rect = new Rect(0, 0, 100, 100);
    
  5. VideoDrawingPlayer プロパティに、作成した MediaPlayer を設定します。

    aVideoDrawing.Player = player;
    
  6. MediaPlayerPlay メソッドを使用して、メディアの再生を開始します。

    // Play the video once.
    player.Play();
    

次の例では、VideoDrawingMediaPlayer を使用して、ビデオ ファイルを 1 回再生します。

//
// Create a VideoDrawing.
//
MediaPlayer player = new MediaPlayer();

player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));

VideoDrawing aVideoDrawing = new VideoDrawing();

aVideoDrawing.Rect = new Rect(0, 0, 100, 100);

aVideoDrawing.Player = player;

// Play the video once.
player.Play();

メディアに対する追加のタイミング制御を取得するには、MediaPlayerVideoDrawing オブジェクトで MediaTimeline を使用します。 MediaTimeline を使用すると、ビデオを繰り返す必要があるかどうかを指定できます。 VideoDrawingMediaTimeline を使用するには、次の手順を実行します。

  1. MediaTimeline を宣言し、そのタイミング動作を設定します。

    // Create a MediaTimeline.
    MediaTimeline mTimeline =
        new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
    
    // Set the timeline to repeat.
    mTimeline.RepeatBehavior = RepeatBehavior.Forever;
    
  2. MediaTimeline から MediaClock を作成します。

    // Create a clock from the MediaTimeline.
    MediaClock mClock = mTimeline.CreateClock();
    
  3. MediaPlayer を作成し、MediaClock を使用してその Clock プロパティを設定します。

    MediaPlayer repeatingVideoDrawingPlayer = new MediaPlayer();
    repeatingVideoDrawingPlayer.Clock = mClock;
    
  4. VideoDrawing を作成し、MediaPlayerVideoDrawingPlayer プロパティに割り当てます。

    VideoDrawing repeatingVideoDrawing = new VideoDrawing();
    repeatingVideoDrawing.Rect = new Rect(150, 0, 100, 100);
    repeatingVideoDrawing.Player = repeatingVideoDrawingPlayer;
    

次の例では、MediaPlayer および VideoDrawing と共に MediaTimeline を使用して、ビデオを繰り返し再生します。

//
// Create a VideoDrawing that repeats.
//

// Create a MediaTimeline.
MediaTimeline mTimeline =
    new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));

// Set the timeline to repeat.
mTimeline.RepeatBehavior = RepeatBehavior.Forever;

// Create a clock from the MediaTimeline.
MediaClock mClock = mTimeline.CreateClock();

MediaPlayer repeatingVideoDrawingPlayer = new MediaPlayer();
repeatingVideoDrawingPlayer.Clock = mClock;

VideoDrawing repeatingVideoDrawing = new VideoDrawing();
repeatingVideoDrawing.Rect = new Rect(150, 0, 100, 100);
repeatingVideoDrawing.Player = repeatingVideoDrawingPlayer;

MediaTimeline を使用する場合は、MediaPlayer の対話型メソッドではなく、MediaClockController プロパティから返された対話型の ClockController を使用して、メディアの再生を制御します。

テキストの描画

テキストを描画するには、GlyphRunDrawingGlyphRun を使用します。 次の例では、GlyphRunDrawing を使用して "Hello World" というテキストを描画します。

GlyphRun theGlyphRun = new GlyphRun(
    new GlyphTypeface(new Uri(@"C:\WINDOWS\Fonts\TIMES.TTF")),
    0,
    false,
    13.333333333333334,
    new ushort[]{43, 72, 79, 79, 82, 3, 58, 82, 85, 79, 71},
    new Point(0, 12.29),
    new double[]{
        9.62666666666667, 7.41333333333333, 2.96,
        2.96, 7.41333333333333, 3.70666666666667,
        12.5866666666667, 7.41333333333333,
        4.44, 2.96, 7.41333333333333},
    null,
    null,
    null,
    null,
    null,
    null

    );

GlyphRunDrawing gDrawing = new GlyphRunDrawing(Brushes.Black, theGlyphRun);
<GlyphRunDrawing ForegroundBrush="Black">
  <GlyphRunDrawing.GlyphRun>
    <GlyphRun 
      CaretStops="{x:Null}" 
      ClusterMap="{x:Null}" 
      IsSideways="False" 
      GlyphOffsets="{x:Null}" 
      GlyphIndices="43 72 79 79 82 3 58 82 85 79 71" 
      BaselineOrigin="0,12.29"  
      FontRenderingEmSize="13.333333333333334" 
      DeviceFontName="{x:Null}" 
      AdvanceWidths="9.62666666666667 7.41333333333333 2.96 2.96 7.41333333333333 3.70666666666667 12.5866666666667 7.41333333333333 4.44 2.96 7.41333333333333" 
      BidiLevel="0">
      <GlyphRun.GlyphTypeface>
        <GlyphTypeface FontUri="C:\WINDOWS\Fonts\TIMES.TTF" />
      </GlyphRun.GlyphTypeface>
    </GlyphRun>
  </GlyphRunDrawing.GlyphRun>
</GlyphRunDrawing>

GlyphRun は、固定形式のドキュメント プレゼンテーションと印刷のシナリオで使用することを意図された低レベルのオブジェクトです。 画面にテキストを描画する簡単な方法は、Label または TextBlock を使用する方法です。 GlyphRun について詳しくは、「GlyphRun オブジェクトと Glyphs 要素の概要」をご覧ください。

複合描画

DrawingGroup を使用すると、複数の描画を 1 つの複合描画に結合できます。 DrawingGroup を使用すると、図形、イメージ、テキストを 1 つの Drawing オブジェクトに結合できます。

次の例では、DrawingGroup を使用して、2 つの GeometryDrawing オブジェクトと ImageDrawing オブジェクトを結合します。 この例を実行すると、次の出力が生成されます。

A DrawingGroup with multiple drawings
複合描画

//
// Create three drawings.
//
GeometryDrawing ellipseDrawing =
    new GeometryDrawing(
        new SolidColorBrush(Color.FromArgb(102, 181, 243, 20)),
        new Pen(Brushes.Black, 4),
        new EllipseGeometry(new Point(50,50), 50, 50)
    );

ImageDrawing kiwiPictureDrawing =
    new ImageDrawing(
        new BitmapImage(new Uri(@"sampleImages\kiwi.png", UriKind.Relative)),
        new Rect(50,50,100,100));

GeometryDrawing ellipseDrawing2 =
    new GeometryDrawing(
        new SolidColorBrush(Color.FromArgb(102,181,243,20)),
        new Pen(Brushes.Black, 4),
        new EllipseGeometry(new Point(150, 150), 50, 50)
    );

// Create a DrawingGroup to contain the drawings.
DrawingGroup aDrawingGroup = new DrawingGroup();
aDrawingGroup.Children.Add(ellipseDrawing);
aDrawingGroup.Children.Add(kiwiPictureDrawing);
aDrawingGroup.Children.Add(ellipseDrawing2);

<DrawingGroup>

  <GeometryDrawing Brush="#66B5F314">
    <GeometryDrawing.Geometry>
      <EllipseGeometry Center="50,50" RadiusX="50"  RadiusY="50"/>
    </GeometryDrawing.Geometry>
    <GeometryDrawing.Pen>
      <Pen Brush="Black" Thickness="4" />
    </GeometryDrawing.Pen>
  </GeometryDrawing>
  <ImageDrawing ImageSource="sampleImages\kiwi.png" Rect="50,50,100,100"/>
  <GeometryDrawing Brush="#66B5F314">
    <GeometryDrawing.Geometry>
      <EllipseGeometry Center="150,150" RadiusX="50"  RadiusY="50"/>
    </GeometryDrawing.Geometry>
    <GeometryDrawing.Pen>
      <Pen Brush="Black" Thickness="4" />
    </GeometryDrawing.Pen>
  </GeometryDrawing>
</DrawingGroup>

また、DrawingGroup を使用すると、不透明マスク、変換、ビットマップ効果などの操作をコンテンツに適用することもできます。 DrawingGroup 操作は、OpacityMaskOpacityBitmapEffectClipGeometryGuidelineSetTransform の順に適用されます。

次の図は、DrawingGroup 操作が適用される順序を示したものです。

DrawingGroup order of operations
DrawingGroup の操作の順序

次の表では、DrawingGroup オブジェクトの内容の操作に使用できるプロパティを説明します。

プロパティ 説明
OpacityMask DrawingGroup の内容の選択した部分の不透明度を変更します。 例については、「方法: 描画の不透明度を制御する」をご覧ください。 A DrawingGroup with an opacity mask
Opacity DrawingGroup の内容の不透明度を一様に変更します。 Drawing を透明または半透明にするには、このプロパティを使用します。 例については、「方法: 不透明マスクを描画に適用する」をご覧ください。 DrawingGroups with different opacity settings
BitmapEffect DrawingGroup の内容に BitmapEffect を適用します。 例については、「方法: BitmapEffect を描画に適用する」をご覧ください。 DrawingGroup with a BlurBitmapEffect
ClipGeometry Geometry を使用して記述した領域に DrawingGroup の内容をクリッピングします。 例については、「方法: 描画をクリッピングする」をご覧ください。 DrawingGroup with a defined clip region
GuidelineSet デバイスに依存しないピクセルを、指定したガイドラインに沿ったデバイス ピクセルにスナップします。 このプロパティは、低解像度ディスプレイで、非常に詳細なグラフィックスがはっきりとレンダリングされるようにするのに便利です。 例については、「方法 : 描画に GuidelineSet を適用する」をご覧ください。 A DrawingGroup with and without a GuidelineSet
Transform DrawingGroup の内容を変換します。 例については、「方法: 変換を描画に適用する」をご覧ください。 A rotated DrawingGroup

描画をイメージとして表示する

Image コントロールで Drawing を表示するには、Image コントロールの Source として DrawingImage を使用し、表示する描画に DrawingImage オブジェクトの DrawingImage.Drawing プロパティを設定します。

次の例では、DrawingImageImage コントロールを使用して GeometryDrawing を表示します。 この例を実行すると、次の出力が生成されます。

A GeometryDrawing of two ellipses
DrawingImage

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SDKSample
{
    public class DrawingImageExample : Page
    {

        public DrawingImageExample()
        {

            //
            // Create the Geometry to draw.
            //
            GeometryGroup ellipses = new GeometryGroup();
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50,50), 45, 20)
                );
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50, 50), 20, 45)
                );

            //
            // Create a GeometryDrawing.
            //
            GeometryDrawing aGeometryDrawing = new GeometryDrawing();
            aGeometryDrawing.Geometry = ellipses;

            // Paint the drawing with a gradient.
            aGeometryDrawing.Brush =
                new LinearGradientBrush(
                    Colors.Blue,
                    Color.FromRgb(204,204,255),
                    new Point(0,0),
                    new Point(1,1));

            // Outline the drawing with a solid color.
            aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);

            //
            // Use a DrawingImage and an Image control
            // to display the drawing.
            //
            DrawingImage geometryImage = new DrawingImage(aGeometryDrawing);

            // Freeze the DrawingImage for performance benefits.
            geometryImage.Freeze();

            Image anImage = new Image();
            anImage.Source = geometryImage;
            anImage.HorizontalAlignment = HorizontalAlignment.Left;

            //
            // Place the image inside a border and
            // add it to the page.
            //
            Border exampleBorder = new Border();
            exampleBorder.Child = anImage;
            exampleBorder.BorderBrush = Brushes.Gray;
            exampleBorder.BorderThickness = new Thickness(1);
            exampleBorder.HorizontalAlignment = HorizontalAlignment.Left;
            exampleBorder.VerticalAlignment = VerticalAlignment.Top;
            exampleBorder.Margin = new Thickness(10);

            this.Margin = new Thickness(20);
            this.Background = Brushes.White;
            this.Content = exampleBorder;
        }
    }
}
<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="PresentationOptions"
  Background="White" Margin="20">

  <Border BorderBrush="Gray" BorderThickness="1" 
    HorizontalAlignment="Left" VerticalAlignment="Top"
    Margin="10">

    <!-- This image uses a Drawing object for its source. -->
    <Image>
      <Image.Source>
        <DrawingImage PresentationOptions:Freeze="True">
          <DrawingImage.Drawing>
            <GeometryDrawing>
              <GeometryDrawing.Geometry>
                <GeometryGroup>
                  <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
                  <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
                </GeometryGroup>
              </GeometryDrawing.Geometry>
              <GeometryDrawing.Brush>
                <LinearGradientBrush>
                  <GradientStop Offset="0.0" Color="Blue" />
                  <GradientStop Offset="1.0" Color="#CCCCFF" />
                </LinearGradientBrush>
              </GeometryDrawing.Brush>
              <GeometryDrawing.Pen>
                <Pen Thickness="10" Brush="Black" />
              </GeometryDrawing.Pen>
            </GeometryDrawing>
          </DrawingImage.Drawing>
        </DrawingImage>
      </Image.Source>
    </Image>
  </Border>

</Page>

描画によるオブジェクトの塗りつぶし

DrawingBrush は、描画オブジェクトで領域を塗りつぶすブラシの一種です。 描画でほとんどすべてのグラフィカル オブジェクトを塗りつぶすために使うことができます。 DrawingBrushDrawing プロパティは、Drawing を記述します。 DrawingBrushDrawing をレンダリングするには、ブラシの Drawing プロパティを使用してブラシにこれを追加し、ブラシを使用してコントロールやパネルなどのグラフィカル オブジェクトを塗りつぶします。

次の例では、DrawingBrush を使用して、GeometryDrawing から作成されたパターンで RectangleFill を塗りつぶします。 この例を実行すると、次の出力が生成されます。

A tiled DrawingBrush
DrawingBrush で使われる GeometryDrawing

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SDKSample
{
    public class DrawingBrushExample : Page
    {

        public DrawingBrushExample()
        {

            //
            // Create the Geometry to draw.
            //
            GeometryGroup ellipses = new GeometryGroup();
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50,50), 45, 20)
                );
            ellipses.Children.Add(
                new EllipseGeometry(new Point(50, 50), 20, 45)
                );

            //
            // Create a GeometryDrawing.
            //
            GeometryDrawing aGeometryDrawing = new GeometryDrawing();
            aGeometryDrawing.Geometry = ellipses;

            // Paint the drawing with a gradient.
            aGeometryDrawing.Brush =
                new LinearGradientBrush(
                    Colors.Blue,
                    Color.FromRgb(204,204,255),
                    new Point(0,0),
                    new Point(1,1));

            // Outline the drawing with a solid color.
            aGeometryDrawing.Pen = new Pen(Brushes.Black, 10);

            DrawingBrush patternBrush = new DrawingBrush(aGeometryDrawing);
            patternBrush.Viewport = new Rect(0, 0, 0.25, 0.25);
            patternBrush.TileMode = TileMode.Tile;
            patternBrush.Freeze();

            //
            // Create an object to paint.
            //
            Rectangle paintedRectangle = new Rectangle();
            paintedRectangle.Width = 100;
            paintedRectangle.Height = 100;
            paintedRectangle.Fill = patternBrush;

            //
            // Place the image inside a border and
            // add it to the page.
            //
            Border exampleBorder = new Border();
            exampleBorder.Child = paintedRectangle;
            exampleBorder.BorderBrush = Brushes.Gray;
            exampleBorder.BorderThickness = new Thickness(1);
            exampleBorder.HorizontalAlignment = HorizontalAlignment.Left;
            exampleBorder.VerticalAlignment = VerticalAlignment.Top;
            exampleBorder.Margin = new Thickness(10);

            this.Margin = new Thickness(20);
            this.Background = Brushes.White;
            this.Content = exampleBorder;
        }
    }
}
<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="PresentationOptions"
  Margin="20" Background="White">

  <Border BorderBrush="Gray" BorderThickness="1" 
    HorizontalAlignment="Left" VerticalAlignment="Top"
    Margin="10">
    <Rectangle Width="100" Height="100">
      <Rectangle.Fill>
        <DrawingBrush PresentationOptions:Freeze="True"
                      Viewport="0,0,0.25,0.25" TileMode="Tile">
          <DrawingBrush.Drawing>
            <GeometryDrawing>
              <GeometryDrawing.Geometry>
                <GeometryGroup>
                  <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
                  <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
                </GeometryGroup>
              </GeometryDrawing.Geometry>
              <GeometryDrawing.Brush>
                <LinearGradientBrush>
                  <GradientStop Offset="0.0" Color="Blue" />
                  <GradientStop Offset="1.0" Color="#CCCCFF" />
                </LinearGradientBrush>
              </GeometryDrawing.Brush>
              <GeometryDrawing.Pen>
                <Pen Thickness="10" Brush="Black" />
              </GeometryDrawing.Pen>
            </GeometryDrawing>
          </DrawingBrush.Drawing>
        </DrawingBrush>
      </Rectangle.Fill>

    </Rectangle>
  </Border>


</Page>

DrawingBrush クラスには、内容を拡大したり並べて表示したりするためのさまざまなオプションが用意されています。 DrawingBrush の詳細については、「イメージ、描画、およびビジュアルによる塗りつぶし」の概要をご覧ください。

ビジュアルで描画をレンダリングする

DrawingVisual は、描画をレンダリングするために設計されたビジュアル オブジェクトの一種です。 高度にカスタマイズされたグラフィカル環境を構築したい開発者は、ビジュアル レイヤーを直接操作できますが、この概要ではそれについては説明しません。 詳しくは、「DrawingVisual オブジェクトの使用」をご覧ください。

DrawingContext オブジェクト

DrawingContext クラスを使用すると、Visual または Drawing にビジュアル コンテンツを設定できます。 このような低レベルのグラフィックス オブジェクトの多くは、グラフィカル コンテンツを非常に効率よく記述できるため、DrawingContext を使用します。

DrawingContext の描画メソッドは System.Drawing.Graphics 型の描画メソッドと見た目は似ていますが、実際にはかなり異なります。 DrawingContext は保持モードのグラフィックス システムで使用されますが、System.Drawing.Graphics 型はイミディエイト モードのグラフィックス システムで使用されます。 DrawingContext オブジェクトの描画コマンドを使用すると、実際には、レンダリング命令のセットが保存され (ただし、厳密な格納メカニズムは DrawingContext を提供するオブジェクトの型に依存します)、後でグラフィックス システムによって使用されます。画面にリアルタイムで描画されることはありません。 Windows Presentation Foundation (WPF) グラフィックス システムの動作方法について詳しくは、「WPF グラフィックス レンダリングの概要」をご覧ください。

DrawingContext を直接インスタンス化することはできません。ただし、描画コンテキストは、特定のメソッド (DrawingGroup.OpenDrawingVisual.RenderOpen など) から取得できます。

ビジュアルの内容の列挙

他の用途に加えて、Drawing オブジェクトでは、Visual の内容を列挙するためのオブジェクト モデルも提供されます。

次の例では、GetDrawing メソッドを使用して VisualDrawingGroup 値を取得し、それを列挙します。

public void RetrieveDrawing(Visual v)
{
    DrawingGroup drawingGroup = VisualTreeHelper.GetDrawing(v);
    EnumDrawingGroup(drawingGroup);
}

// Enumerate the drawings in the DrawingGroup.
public void EnumDrawingGroup(DrawingGroup drawingGroup)
{
    DrawingCollection dc = drawingGroup.Children;

    // Enumerate the drawings in the DrawingCollection.
    foreach (Drawing drawing in dc)
    {
        // If the drawing is a DrawingGroup, call the function recursively.
        if (drawing is DrawingGroup group)
        {
            EnumDrawingGroup(group);
        }
        else if (drawing is GeometryDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is ImageDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is GlyphRunDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is VideoDrawing)
        {
            // Perform action based on drawing type.
        }
    }
}

関連項目