パフォーマンスの最適化: 2D グラフィックスとイメージング

WPF には、アプリケーションの要件に合わせて最適化できる広範な 2D グラフィックス機能とイメージング機能が用意されています。 このトピックでは、この領域でのパフォーマンスの最適化に関する情報を提供します。

描画と図形

WPF には、グラフィカルな描画コンテンツを表現するために DrawingShape の両方のオブジェクトが用意されています。 ただし、Drawing オブジェクトの方が Shape オブジェクトよりコンストラクトが簡単であり、パフォーマンス特性に優れています。

Shape を使用すると、画面にグラフィカルな図形を描画できます。 FrameworkElement オブジェクトは Shape クラスから派生するため、パネルおよびほとんどのコントロール内で使用できます。

WPF には、グラフィックス サービスやレンダリング サービスへのアクセスのレイヤーがいくつか用意されています。 Shape オブジェクトは最上位レイヤーで使いやすく、レイアウトやイベント処理などの便利な機能が多数提供されます。 WPF には、すぐに使用できるさまざまな図形オブジェクトが用意されています。 すべての図形オブジェクトは Shape クラスを継承します。 使用可能な図形オブジェクトには EllipseLinePathPolygonPolylineRectangle があります。

一方、Drawing オブジェクトは FrameworkElement クラスから派生せず、図形、イメージ、テキストを描画するためのより軽量な実装が提供されます。

Drawing オブジェクトには、次の 4 種類があります。

  • GeometryDrawing 図形が描画されます。

  • ImageDrawing 画像が描画されます。

  • GlyphRunDrawing テキストが描画されます。

  • DrawingGroup その他の図が描画されます。 他の描画を 1 つの複合描画に結合するには、描画グループを使用します。

GeometryDrawing オブジェクトは、ジオメトリ コンテンツをレンダリングするために使用されます。 Geometry クラスと、それから派生する具象クラス (CombinedGeometryEllipseGeometryPathGeometry など) では、2D グラフィックスをレンダリングするための手段と、ヒット テストやクリッピングのサポートが提供されています。 ジオメトリ オブジェクトを使用すると、たとえば、コントロールの領域を定義したり、イメージに適用するクリップ領域を定義したりすることができます。 ジオメトリ オブジェクトは、四角形や円などの単純な領域にすることも、2 つ以上のジオメトリ オブジェクトから作成された複合的な領域にすることもできます。 さらに複雑な幾何学領域を作成するには、PathSegment 派生オブジェクト (ArcSegmentBezierSegmentQuadraticBezierSegment など) の組み合わせを使用します。

表面的には、Geometry クラスと Shape クラスは似ています。 いずれのクラスも 2D グラフィックスのレンダリングに使用され、それぞれのクラスから派生する具象クラスも似ています (EllipseGeometryEllipse など)。 ただし、この 2 つのクラスのセットの間には重要な違いがいくつかあります。 その 1 つとして、Geometry クラスには、Shape クラスの一部の機能 (図形そのものを描画する機能など) がありません。 ジオメトリ オブジェクトを描画するには、DrawingContext、Drawing、Path (Path が Shape であることは注目に値します) などの別のクラスを使用して描画操作を実行する必要があります。 塗りつぶし、ストローク、ストロークの太さなどの描画プロパティは、ジオメトリ オブジェクトを描画するクラスにあります。一方、図形オブジェクトにはこれらのプロパティが含まれています。 この違いは、ジオメトリ オブジェクトでは円などの領域が定義されるのに対し、図形オブジェクトでは領域が定義されるとともに、その領域の塗りつぶしやアウトラインも定義され、レイアウト システムに参加する、と考えることができます。

Shape オブジェクトは FrameworkElement クラスから派生するため、Shape オブジェクトを使用するとアプリケーションのメモリ消費が大幅に増加する可能性があります。 グラフィカル コンテンツで FrameworkElement の機能がまったく必要ない場合は、より軽量な Drawing オブジェクトを使用することを検討します。

Drawing オブジェクトの詳細については、「Drawing オブジェクトの概要」を参照してください。

StreamGeometry オブジェクト

StreamGeometry オブジェクトは、幾何学図形を作成するための PathGeometry の代替となる軽量なものです。 StreamGeometry は、複雑なジオメトリを作成する必要がある場合に使用します。 StreamGeometry は、多数の PathGeometry オブジェクトを処理することを想定して最適化されているため、多数の PathGeometry オブジェクトを個別に使用する場合に比べてパフォーマンスが向上します。

次の例では、XAML で属性構文の使用によって三角形の StreamGeometry が作成されます。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel>
  
    <Path Data="F0 M10,100 L100,100 100,50Z" 
      StrokeThickness="1" Stroke="Black"/>

  </StackPanel>
</Page>

StreamGeometry オブジェクトの詳細については、「StreamGeometry を使用して図形を作成する」を参照してください。

DrawingVisual オブジェクト

DrawingVisual オブジェクトは、図形、画像、またはテキストのレンダリングに使用する軽量の描画クラスです。 このクラスが軽量と見なされる理由は、レイアウトやイベントの処理を行わないことで、パフォーマンスが向上するからです。 そのため、背景やクリップ アートの描画に適しています。 詳しくは、「DrawingVisual オブジェクトの使用」を参照してください。

イメージ

WPF のイメージング機能は、以前のバージョンの Windows のイメージング機能から大幅に強化されています。 イメージング機能 (ビットマップの表示や一般的なコントロール上でのイメージの使用など) は、以前は主に Microsoft Windows Graphics Device Interface (GDI) または Microsoft Windows GDI+ のアプリケーション プログラミング インターフェイス (API) によって処理されていました。 これらの API では、基本的なイメージング機能は提供されていましたが、コーデック拡張機能のサポートや高品質なイメージのサポートなどの機能が不足していました。 WPF Imaging API は、GDI および GDI+ の欠点を克服し、アプリケーション内でイメージを表示および使用するための新しい API のセットを提供するために再設計されています。

イメージを使用する際には、パフォーマンスを向上させるために以下の推奨事項をご検討ください。

  • アプリケーションでサムネイル イメージを表示する必要がある場合は、縮小版のイメージを作成することをご検討ください。 既定では、WPF は読み込んだイメージを本来のサイズにデコードします。 サムネイル バージョンのイメージのみが必要な場合は、WPF がイメージを本来のサイズにデコードしてからサムネイル サイズに縮小するという無駄が生じます。 この不要なオーバーヘッドを回避するには、WPF に対してイメージをサムネイル サイズにデコードするように要求するか、WPF にサムネイル サイズのイメージを読み込むように要求します。

  • イメージは常に、既定のサイズではなく必要なサイズにデコードするようにしてください。 前述のように、既定の実際のサイズではなく必要なサイズにイメージをデコードするように WPF に要求します。 これにより、アプリケーションの作業セットを縮小できるだけでなく、実行速度も向上します。

  • 可能であれば、複数のイメージを 1 つに結合します (複数のイメージから成るフィルム ストリップなど)。

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

BitmapScalingMode

ビットマップのスケーリングをアニメーション化する場合、既定の高品質イメージの再サンプリング アルゴリズムは、フレーム レートを低下させるほどシステム リソースを消費する場合があり、実際にはアニメーションの動きが滑らかでなくなることがあります。 RenderOptions オブジェクトの BitmapScalingMode プロパティを LowQuality に設定することで、ビットマップをスケーリングするときに、より滑らかなアニメーションを作成できます。 LowQuality モードでは、WPF のレンダリング エンジンに対し、イメージを処理するときに品質重視のアルゴリズムから速度重視のアルゴリズムに切り替えるように指示されます。

イメージ オブジェクトの BitmapScalingMode を設定する方法の例を次に示します。

// Set the bitmap scaling mode for the image to render faster.
RenderOptions.SetBitmapScalingMode(MyImage, BitmapScalingMode.LowQuality);
' Set the bitmap scaling mode for the image to render faster.
RenderOptions.SetBitmapScalingMode(MyImage, BitmapScalingMode.LowQuality)

CachingHint

既定の WPF では、TileBrush オブジェクト (DrawingBrushVisualBrush など) のレンダリングされた内容はキャッシュされません。 シーンで TileBrush の内容も使用も変化しない静的なシナリオでは、ビデオ メモリが節約されるため、これには意味があります。 静的な内容の TileBrush を静的でない方法で使用する場合には、あまり意味はありません。たとえば、静的な DrawingBrushVisualBrush が回転する 3D オブジェクトのサーフェイスにマップされている場合などです。 WPF の既定の動作では、内容が変化しない場合でも、DrawingBrush または VisualBrush のすべてのフレームの内容全体が再レンダリングされます。

RenderOptions オブジェクトの CachingHint プロパティを Cache に設定すると、並べて表示されたブラシ オブジェクトのキャッシュ バージョンを使用してパフォーマンスを向上させることができます。

CacheInvalidationThresholdMinimum プロパティと CacheInvalidationThresholdMaximum プロパティの値は、スケールの変化に伴って TileBrush オブジェクトをいつ再生成する必要があるかを決定する相対的なサイズ値です。 たとえば、CacheInvalidationThresholdMaximum プロパティを 2.0 に設定すると、TileBrush のキャッシュ サイズが現在のキャッシュ サイズの倍を超えた場合にだけ、キャッシュを再生成すれば済みます。

DrawingBrush のキャッシュ ヒント オプションの使用方法の例を次に示します。

DrawingBrush drawingBrush = new DrawingBrush();

// Set the caching hint option for the brush.
RenderOptions.SetCachingHint(drawingBrush, CachingHint.Cache);

// Set the minimum and maximum relative sizes for regenerating the tiled brush.
// The tiled brush will be regenerated and re-cached when its size is
// 0.5x or 2x of the current cached size.
RenderOptions.SetCacheInvalidationThresholdMinimum(drawingBrush, 0.5);
RenderOptions.SetCacheInvalidationThresholdMaximum(drawingBrush, 2.0);
Dim drawingBrush As New DrawingBrush()

' Set the caching hint option for the brush.
RenderOptions.SetCachingHint(drawingBrush, CachingHint.Cache)

' Set the minimum and maximum relative sizes for regenerating the tiled brush.
' The tiled brush will be regenerated and re-cached when its size is
' 0.5x or 2x of the current cached size.
RenderOptions.SetCacheInvalidationThresholdMinimum(drawingBrush, 0.5)
RenderOptions.SetCacheInvalidationThresholdMaximum(drawingBrush, 2.0)

関連項目