今日您是第次访问
设为主页
添加改藏
网站优化
 
了解WPF技术
Silverlight WPF/E教程
WPF应用程序教程
当前位置:网站主页->WPF性能->文章浏览

WPF二维图形和图像处理

日期:2008-9-27 来源:MSDN 制作:yoling group

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

本主题包括下列各节。

 绘图和形状

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="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 对象

 图像

与以前版本的 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);    

CachingHint

默认情况下,WPF 不缓存 TileBrush 对象(例如 DrawingBrushVisualBrush)的已呈现内容。在内容或场景中对 TileBrush 的使用均不更改的静态情况下,此功能很有用,因为它可以节省视频内存。在以非静态方式使用具有静态内容的 TileBrush 时(例如当静态的 DrawingBrushVisualBrush 映射到旋转三维对象的表面时),此功能的作用不大。WPF 的默认行为是逐帧重新呈现 DrawingBrushVisualBrush 的整个内容,即使内容没有更改也是如此。

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

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

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

// Set the minimum and maximum relative sizes for regenerating the tiled brush.  RenderOptions.SetCacheInvalidationThresholdMinimum(drawingBrush, 0.5);  RenderOptions.SetCacheInvalidationThresholdMaximum(drawingBrush, 2.0);    // The tiled brush will be regenerated when the size is  //   0.5x, 0.25x (and so forth)  // and  //   2x, 4x, 8x (and so forth)  // of the original size.    // Set the caching hint option for the brush.  RenderOptions.SetCachingHint(drawingBrush, CachingHint.Cache);