Optimieren der Leistung: 2D-Grafiken und Bildverarbeitung

WPF stellt zahlreiche Funktionen für 2D-Grafiken und Bildverarbeitung zur Verfügung, die den Anforderungen Ihrer Anwendung entsprechend optimiert werden können. Dieses Thema enthält Informationen über die Leistungsoptimierung in diesen Bereichen.

Zeichnen und Formen

WPF stellt sowohl Drawing- als auch Shape-Objekte bereit, die grafische Zeichnungsinhalte darstellen. Allerdings sind Drawing-Objekte einfachere Konstrukte als Shape-Objekte und bieten bessere Leistungsmerkmale.

Mit Shape können Sie eine grafische Form auf dem Bildschirm zeichnen. Da sie von der FrameworkElement-Klasse abgeleitet werden, können Shape-Objekte in Paneln und den meisten Steuerelementen verwendet werden.

WPF bietet mehrere Ebenen für den Zugriff auf Grafiken und Renderingdienste. Auf der obersten Ebene stehen die benutzerfreundlichen Shape-Objekte mit einer Vielzahl von nützlichen Funktionen zur Verfügung, z. B. Layout und Ereignisbehandlung. WPF stellt eine Reihe von vorgefertigten Shape-Objekten zur Verfügung. Alle Shape-Objekte erben von der Shape-Klasse. Verfügbare Shape-Objekte sind Ellipse, Line, Path, Polygon, Polyline und Rectangle.

Drawing-Objekte werden dagegen nicht von der FrameworkElement-Klasse abgeleitet und bieten eine einfache Implementierung für das Rendering von Formen, Bildern und Text.

Es gibt vier Typen von Drawing-Objekten:

Das Objekt GeometryDrawing wird zum Rendern von geometrischen Inhalten verwendet. Die Geometry-Klasse und die von ihr abgeleiteten konkreten Klassen wie CombinedGeometry, EllipseGeometry und PathGeometry ermöglichen das Rendern von 2D-Grafiken und bieten Unterstützung für Treffertests und Clipping. Mit Geometry-Objekten können beispielsweise der Bereich eines Steuerelements oder der auf ein Bild anzuwendende Clip-Bereich definiert werden. Bei Geometry-Objekten kann es sich um einfache Bereiche wie Rechtecke und Kreise oder um aus einem oder mehreren geometrischen Objekten zusammengesetzte Regionen handeln. Komplexere geometrische Bereiche können erstellt werden, indem sie von PathSegment abgeleitete Objekte wie ArcSegment, BezierSegment und QuadraticBezierSegment kombinieren.

Oberflächlich betrachtet sind die Geometry-Klasse und die Shape-Klasse ähnlich. Beide werden bei der Darstellung von 2D-Grafiken verwendet, und beide haben ähnliche konkrete Klassen, die von ihnen abgeleitet werden, beispielsweise EllipseGeometry und Ellipse. Es gibt jedoch wichtige Unterschiede zwischen diesen zwei Sätzen von Klassen. Zum einen fehlt der Klasse Geometry ein Teil der Funktionalität der Klasse Shape, z. B. die Fähigkeit, sich selbst zu zeichnen. Zum Zeichnen eines Geometry-Objekts muss eine andere Klasse, beispielsweise DrawingContext, Drawing oder Path (dabei ist zu beachten, dass ein Path eine Shape ist), verwendet werden, um den Zeichnungsvorgang auszuführen. Renderingeigenschaften wie Füllung, Strich und Strichstärke befinden sich in der Klasse, die das Geometry-Objekt zeichnet, während ein Shape-Objekt diese Eigenschaften enthält. Eine Möglichkeit zur Annäherung an diesen Unterschied besteht darin, dass ein Geometry-Objekt einen Bereich definiert, z. B. einen Kreis, während ein Shape-Objekt definiert, wie dieser Bereich gefüllt und konturiert wird und eine Komponente des Layoutsystems ist.

Da Shape-Objekte von der FrameworkElement-Klasse abgeleitet werden, kann die Verwendung dieser Objekte den Speicherverbrauch in Ihrer Anwendung erheblich erhöhen. Wenn Sie die FrameworkElement-Funktionen für Ihren grafischen Inhalt nicht wirklich benötigen, sollten Sie die schlankeren Drawing-Objekte verwenden.

Weitere Informationen zu Drawing-Objekten finden Sie unter Übersicht über Zeichnungsobjekte.

StreamGeometry-Objekte

Das Objekt StreamGeometry ist eine schlanke Alternative zu PathGeometry für das Erstellen geometrischer Formen. Verwenden Sie StreamGeometry, wenn Sie eine komplexe Geometrie beschreiben müssen. StreamGeometry ist für die Verarbeitung von vielen PathGeometry-Objekten optimiert und schneidet im Vergleich zu vielen einzelnen PathGeometry-Objekten besser ab.

Im folgenden Beispiel wird mithilfe der Attributsyntax eine dreieckige StreamGeometry in XAML erstellt.

<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>

Weitere Informationen zu StreamGeometry-Objekten finden Sie unter Erstellen einer Form mithilfe von StreamGeometry.

DrawingVisual-Objekte

Das DrawingVisual-Objekt ist eine einfache Zeichnungsklasse zum Rendern von Formen, Bildern oder Text. Diese Klasse wird als einfach angesehen, weil sie weder Layout noch Ereignisbehandlung bereitstellt. Dadurch wird die Leistung gesteigert. Aus diesem Grund eignen sich Zeichnungen für Hintergründe und ClipArt. Weitere Informationen finden Sie unter Verwenden von DrawingVisual-Objekten.

Bilder

WPF-Bildverarbeitung stellt gegenüber den Bildverarbeitungsfähigkeiten in vorherigen Versionen von Windows eine deutliche Verbesserung dar. Die Bildverarbeitungsfähigkeiten wie das Anzeigen einer Bitmap oder das Verwenden eines Bilds für ein allgemeines Steuerelement wurden hauptsächlich von Microsoft Windows Graphics Device Interface (GDI) oder der Microsoft Windows GDI+-API behandelt. Diese APIs haben Baseline-Bildverarbeitungsfunktionen bereitgestellt, hatten aber keine Features wie die Unterstützung von Codec-Erweiterbarkeit und hochwertigen Bildern. Die WPF-Bildverarbeitungs-APIs wurden neu entworfen, um die Nachteile von GDI und GDI+ zu beheben und einen neuen Satz von APIs bereitzustellen, um Bilder in den Anwendungen anzeigen und verwenden können.

Beim Verwenden von Bildern sollten Sie die folgenden Empfehlungen in Betracht ziehen, um eine bessere Leistung zu erzielen:

  • Wenn Ihre Anwendung die Anzeige von Miniaturbildern erfordert, ist das Erstellen einer Bildversion in reduzierter Größe ratsam. Standardmäßig lädt WPF das Bild und decodiert es in seine vollständige Größe. Wenn Sie nur eine Miniaturansicht des Bilds möchten, decodiert WPF das Bild überflüssigerweise in seine vollständige Größe und skaliert es dann auf die Größe der Miniaturansicht. Um diesen unnötigen Aufwand zu vermeiden, können Sie entweder bei WPF eine Decodierung des Bilds in Miniaturansichtgröße anfordern oder WPF zum Laden eines Bilds in Miniaturansichtgröße auffordern.

  • Decodieren Sie das Bild immer in die gewünschte Größe und nicht in die Standardgröße. Wie bereits erwähnt, fordern Sie bei WPF eine Decodierung des Bilds in die gewünschte Größe und nicht in die vollständige Größe an. Auf diese Weise reduzieren Sie nicht nur das Workingset der Anwendung, Sie erhöhen auch die Ausführungsgeschwindigkeit.

  • Kombinieren Sie die Bilder nach Möglichkeit in einem Einzelbild (z.B. ein Filmstreifen, der sich aus mehreren Bildern zusammensetzt).

  • Weitere Informationen finden Sie unter Übersicht über die Bildverarbeitung.

BitmapScalingMode

Beim Animieren der Skalierung von Bitmaps kann der Standardalgorithmus für das Resampling von Bildern hoher Qualität zuweilen einen solchen Umfang an Systemressourcen beanspruchen, dass eine Verringerung der Einzelbildrate auftritt und Animationen ruckartig wiedergegeben werden. Wenn Sie die BitmapScalingMode-Eigenschaft des RenderOptions-Objekts auf LowQuality festlegen, können Sie beim Skalieren einer Bitmap eine flüssigere Animation erstellen. Der LowQuality-Modus weist die Rendering-Engine von WPF an, beim Verarbeiten von Bildern von einem qualitätsoptimierten Algorithmus auf einen geschwindigkeitsoptimierten Algorithmus umzuschalten.

Im folgenden Beispiel wird das Festlegen des BitmapScalingMode für ein Bildobjekt veranschaulicht.

// 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

Standardmäßig speichert WPF den gerenderten Inhalt von TileBrush-Objekten wie DrawingBrush und VisualBrush nicht zwischen. In statischen Szenarios, in denen sich der Inhalt und die Verwendung von TileBrush in der Szene nicht ändern, ist dies sinnvoll, da Videospeicher gespart wird. Es macht nicht so viel Sinn, wenn ein TileBrush mit statischem Inhalt auf nicht statische Weise verwendet wird – beispielsweise, wenn ein statischer DrawingBrush oder VisualBrush auf der Oberfläche eines rotierenden 3D-Objekts abgebildet wird. Das Standardverhalten von WPF besteht darin, den gesamten Inhalt von DrawingBrush oder VisualBrush für jeden Frame neu zu rendern, auch wenn sich der Inhalt nicht ändert.

Wenn Sie die CachingHint-Eigenschaft des RenderOptions-Objekts auf Cache festlegen, können Sie die Leistung steigern, indem Sie zwischengespeicherte Versionen der Kacheleffektobjekte verwenden.

Die CacheInvalidationThresholdMinimum- und CacheInvalidationThresholdMaximum-Eigenschaftswerte sind relative Größenwerte, die bestimmen, wann das TileBrush-Objekt aufgrund von Maßstabsänderungen neu generiert werden soll. Wenn Sie beispielsweise die Eigenschaft CacheInvalidationThresholdMaximum auf 2,0 festlegen, muss der Cache für TileBrush nur dann neu generiert werden, wenn seine Größe das Doppelte des aktuellen Cache übersteigt.

Im folgenden Beispiel wird die Verwendung der Option für Zwischenspeicherhinweise für einen DrawingBrush gezeigt.

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)

Weitere Informationen