优化性能:二维图形和图像处理

WPF 提供了多种二维图形和图像处理功能,可以针对您的应用程序要求优化这些功能。 本主题提供有关二维图形和图像处理性能优化的信息。

本主题包括下列各节。

  • 绘图和形状
  • StreamGeometry 对象
  • DrawingVisual 对象
  • 图像
  • 相关主题

绘图和形状

WPF 提供了 DrawingShape 这两个对象以表示绘图内容。 不过,Drawing 对象比 Shape 对象结构简单并且性能特性更为优良。

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

WPF 提供了对图形和呈现服务的若干层访问。 在顶层,Shape 对象很容易使用,并且提供了许多有用的功能,例如布局和事件处理。 WPF 提供了大量随时可用的形状对象。 所有形状对象都是从 Shape 类继承的。 可用的形状对象有 EllipseLinePathPolygonPolylineRectangle

Drawing 对象不是派生自 FrameworkElement 类,相比而言它更轻量地实现形状、图像和文本的呈现。

有以下四种类型的 Drawing 对象:

GeometryDrawing 对象用于呈现几何图形内容。 Geometry 类以及从中派生的具体类(如 CombinedGeometryEllipseGeometryPathGeometry)提供二维图形的呈现方式,此外还提供命中测试和剪辑支持。 例如,Geometry 对象可用于定义控件的区域,或者定义要应用到图像的剪辑区域。 Geometry 对象可以是简单的区域(如矩形和圆形),也可以是基于两个或多个几何图形对象创建的复合区域。 通过组合 PathSegment 派生的对象(例如 ArcSegmentBezierSegmentQuadraticBezierSegment),可以创建较复杂的几何图形区域。

从表面上看,Geometry 类和 Shape 类十分相似。 它们都可用来呈现二维图形,并且从其自身派生的具体类也很相似,例如 EllipseGeometryEllipse。 然而,这两种类之间存在着重大差异。 其中有一个差异就是 Geometry 类没有 Shape 类的某些功能,例如自行绘制的功能。 若要绘制一个几何图形对象,必须使用其他类(例如 DrawingContext、Drawing 或 Path,需要注意 Path 是一种 Shape)来执行此绘制操作。 诸如填充、笔画和笔画粗细之类的呈现属性针对绘制此几何图形对象的类,而形状对象包括这些属性。 可以这样来理解此差异:几何图形对象定义一个区域(如圆形),而形状对象不仅定义一个区域,还定义如何填充和描绘此区域并参与布局系统。

由于 Shape 对象派生自 FrameworkElement 类,因此使用此对象会大大增加应用程序的内存消耗。 如果事实上您的图形内容无需使用 FrameworkElement 功能,则可以考虑使用轻量的 Drawing 对象。

有关 Drawing 对象的更多信息,请参见 Drawing 对象概述

StreamGeometry 对象

StreamGeometry 对象是 PathGeometry 的一个轻量替代品,可用于创建几何形状。 若要描述复杂的几何图形,请使用 StreamGeometryStreamGeometry 是经过优化的,可用于处理多个 PathGeometry 对象,并且相对于使用多个独立的 PathGeometry 对象而言,其执行效率更高。

下面的示例使用特性语法用 XAML 创建一个三角形 StreamGeometry

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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 对象

图像

与以前版本的 Windows 中的图像处理功能相比,WPF 图像处理功能有很大的改进。 图像处理功能(例如在常用控件上显示位图或使用图像)主要由 Microsoft Windows 图形设备接口 (GDI) 或 Microsoft Windows GDI+ 应用程序编程接口 (API) 来处理。 这些 API 提供了基线图像处理功能,但缺乏诸如编解码器扩展性支持和高保真图像支持之类的功能。 WPF 图像处理 API 已进行重新设计以克服 GDI 和 GDI+ 的缺点,并提供一组新的 API 用于在应用程序中显示和使用图像。

使用图像时,为了获得更好的性能,请考虑下面的建议:

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

  • 始终将图像解码为所需的大小而不是默认的大小。 如上所述,请求 WPF 将图像解码为所需的大小,而不是默认的完整大小。 这样不仅缩小了应用程序的工作集,而且还提高了执行速度。

  • 如有可能,可以将多个图像组合成单个图像,例如将多个图像组合成一个幻灯胶片。

  • 有关更多信息,请参见图像处理概述

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 映射到旋转三维对象的表面时,此功能的作用不大。 WPF 的默认行为是逐帧重新呈现 DrawingBrushVisualBrush 的整个内容,即使内容没有更改也是如此。

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

CacheInvalidationThresholdMinimumCacheInvalidationThresholdMaximum 属性值是相对大小值,可确定由于比例更改而应重新生成 TileBrush 对象的时间。 例如,如果将 CacheInvalidationThresholdMaximum 属性设置为 2.0,则仅当 TileBrush 的缓存大小超过当前缓存大小的两倍时,才需要重新生成。

下面的示例演示如何将缓存提示选项用于 DrawingBrush

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

请参见

概念

优化 WPF 应用程序性能

规划应用程序性能

优化性能:利用硬件

优化性能:布局和设计

优化性能:对象行为

优化性能:应用程序资源

优化性能:文本

优化性能:数据绑定

优化性能:其他建议

动画提示和技巧