优化性能:2D 图形和图像处理

WPF 提供广泛的 2D 图形和图像处理功能,可针对应用程序要求进行优化。 本主题提供有关这些领域的性能优化的信息。

绘图和形状

WPF 提供DrawingShape对象来表示图形绘制内容。 但是, Drawing 对象比 Shape 对象更简单,并提供更好的性能特征。

使用 A Shape 可将图形形状绘制到屏幕。 由于它们派生自 FrameworkElement 类, Shape 因此可以在面板和大多数控件内使用对象。

WPF 提供对图形和渲染服务的多层访问。 在顶层, Shape 对象易于使用并提供许多有用的功能,例如布局和事件处理。 WPF 提供了许多现成的形状对象。 所有形状对象都继承自 Shape 类。 可用的形状对象包括Ellipse、、PathLinePolygonPolylineRectangle

Drawing 另一方面,对象不派生自 FrameworkElement 类,并提供较轻的实现来呈现形状、图像和文本。

有四种类型的 Drawing 对象:

GeometryDrawing 对象用于呈现几何图形内容。 Geometry类及其派生的具体类,例如CombinedGeometryEllipseGeometry以及PathGeometry,提供了呈现2D图形并支持命中测试及剪裁的方法。 几何图形对象可用于定义控件的区域,例如,或定义要应用于图像的剪辑区域。 几何对象可以是简单的区域,例如矩形和圆,或者从两个或多个几何对象创建的复合区域。 可以通过组合 PathSegment派生对象(例如 ArcSegmentBezierSegmentQuadraticBezierSegment)来创建更复杂的几何区域。

在表面上, Geometry 类和 Shape 类相似。 两者都用于 2D 图形的呈现,并且都具有从它们派生的类似具体类, EllipseGeometry 例如和 Ellipse。 但是,这两组类之间存在重要差异。 例如,Geometry 类缺少 Shape 类的一些功能,比如绘制自身的能力。 若要绘制几何对象,必须使用另一个类(如 DrawingContext、Drawing 或 Path)(值得注意的是,Path 是一种形状)来执行绘图操作。 呈现属性(如填充、笔划和笔划粗细)位于绘制几何图形对象的类上,而形状对象包含这些属性。 思考这种差异的一种方法是,几何对象定义区域,例如圆,而形状对象定义区域,定义该区域的填充和轮廓方式,以及参与布局系统。

由于 Shape 对象派生自 FrameworkElement 类,因此使用这些对象可以显著增加应用程序中的内存消耗。 如果真的不需要 FrameworkElement 图形内容的功能,请考虑使用更轻量 Drawing 的对象。

有关对象的详细信息 Drawing ,请参阅 “绘图对象概述”。

StreamGeometry 对象

StreamGeometry 对象是用于创建几何形状的轻型替代方法 PathGeometry 。 需要描述复杂几何图形时,请使用StreamGeometryStreamGeometry与使用多个单个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 图形设备接口(GDI)或Microsoft Windows GDI+ 应用程序编程接口(API)处理。 这些 API 提供了基线映像功能,但缺少支持编解码器扩展性和高保真图像支持等功能。 WPF 映像 API 经过重新设计,可以克服 GDI 和 GDI+ 的缺点,并提供一组新的 API 来在应用程序中显示和使用图像。

使用映像时,请考虑以下建议以获得更好的性能:

  • 如果应用程序要求显示缩略图图像,请考虑创建图像的缩小版本。 默认情况下,WPF 加载图像并将其解码为其完整大小。 如果只需要图像的缩略图版本,WPF 不需要将图像解码为其完整大小,然后将其缩减为缩略图大小。 为了避免这种不必要的开销,可以请求 WPF 将图像解码为缩略图大小,或请求 WPF 加载缩略图大小图像。

  • 始终将图像解码为所需大小,而不是将图像解码为默认大小。 如上所述,请求 WPF 将图像解码为所需的大小,而不是默认的完整大小。 不仅可以减少应用程序的工作集,还可以降低执行速度。

  • 如果可能,将图像合并为单个图像,例如由多个图像组成的电影条。

  • 有关详细信息,请参阅 映像概述

BitmapScalingMode

对任何位图进行缩放动画处理时,默认的高质量图像重新采样算法有时会消耗大量系统资源,导致帧速率下降,从而有效地导致动画卡顿。 通过将BitmapScalingMode属性设置为LowQuality,您可以在对RenderOptions对象进行缩放时创建更流畅的动画。 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。 在情境中< c0 />的内容或使用不变时,这很合理,因为它节省视频内存。 当具有静态内容的 TileBrush 以动态方式使用时,例如,当静态 DrawingBrushVisualBrush 被映射到旋转的 3D 对象表面时,这就没有那么有意义。 WPF 的默认行为是针对每个帧,即使内容不变,也要重新渲染 DrawingBrushVisualBrush 的整个内容。

通过将对象的属性RenderOptions设置为CachingHintCache,可以使用平铺画笔对象的缓存版本来提高性能。

CacheInvalidationThresholdMinimumCacheInvalidationThresholdMaximum属性值是相对大小值,用于确定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)

另请参阅