WPF 提供广泛的 2D 图形和图像处理功能,可针对应用程序要求进行优化。 本主题提供有关这些领域的性能优化的信息。
绘图和形状
WPF 提供Drawing和Shape对象来表示图形绘制内容。 但是, Drawing 对象比 Shape 对象更简单,并提供更好的性能特征。
使用 A Shape 可将图形形状绘制到屏幕。 由于它们派生自 FrameworkElement 类, Shape 因此可以在面板和大多数控件内使用对象。
WPF 提供对图形和渲染服务的多层访问。 在顶层, Shape 对象易于使用并提供许多有用的功能,例如布局和事件处理。 WPF 提供了许多现成的形状对象。 所有形状对象都继承自 Shape 类。 可用的形状对象包括Ellipse、、PathLine、Polygon和PolylineRectangle。
Drawing 另一方面,对象不派生自 FrameworkElement 类,并提供较轻的实现来呈现形状、图像和文本。
有四种类型的 Drawing 对象:
GeometryDrawing 绘制形状。
ImageDrawing 绘制图像。
GlyphRunDrawing 绘制文本。
DrawingGroup 绘制其他绘图。 使用绘图组将其他绘图合并成单个复合绘图。
该 GeometryDrawing 对象用于呈现几何图形内容。 Geometry类及其派生的具体类,例如CombinedGeometry、EllipseGeometry以及PathGeometry,提供了呈现2D图形并支持命中测试及剪裁的方法。 几何图形对象可用于定义控件的区域,例如,或定义要应用于图像的剪辑区域。 几何对象可以是简单的区域,例如矩形和圆,或者从两个或多个几何对象创建的复合区域。 可以通过组合 PathSegment派生对象(例如 ArcSegment, BezierSegment和 QuadraticBezierSegment)来创建更复杂的几何区域。
在表面上, Geometry 类和 Shape 类相似。 两者都用于 2D 图形的呈现,并且都具有从它们派生的类似具体类, EllipseGeometry 例如和 Ellipse。 但是,这两组类之间存在重要差异。 例如,Geometry 类缺少 Shape 类的一些功能,比如绘制自身的能力。 若要绘制几何对象,必须使用另一个类(如 DrawingContext、Drawing 或 Path)(值得注意的是,Path 是一种形状)来执行绘图操作。 呈现属性(如填充、笔划和笔划粗细)位于绘制几何图形对象的类上,而形状对象包含这些属性。 思考这种差异的一种方法是,几何对象定义区域,例如圆,而形状对象定义区域,定义该区域的填充和轮廓方式,以及参与布局系统。
由于 Shape 对象派生自 FrameworkElement 类,因此使用这些对象可以显著增加应用程序中的内存消耗。 如果真的不需要 FrameworkElement 图形内容的功能,请考虑使用更轻量 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 图形设备接口(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 ,例如 DrawingBrush 和 VisualBrush。 在情境中< c0 />的内容或使用不变时,这很合理,因为它节省视频内存。 当具有静态内容的 TileBrush 以动态方式使用时,例如,当静态 DrawingBrush 或 VisualBrush 被映射到旋转的 3D 对象表面时,这就没有那么有意义。 WPF 的默认行为是针对每个帧,即使内容不变,也要重新渲染 DrawingBrush 或 VisualBrush 的整个内容。
通过将对象的属性RenderOptions设置为CachingHintCache,可以使用平铺画笔对象的缓存版本来提高性能。
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)