最佳化效能:2D 圖形和影像處理
更新:2007 年 11 月
WPF 提供大範圍的 2D 圖形和影像處理功能,可予以最佳化以符合應用程式的需求。本主題提供那些區域的效能最佳化資訊。
這個主題包含下列章節。
- 繪圖和圖案
- StreamGeometry 物件
- DrawingVisual 物件
- 影像
- 相關主題
繪圖和圖案
WPF 提供 Drawing 和 Shape 物件來表示圖形繪圖內容。不過,Drawing 物件是比 Shape 物件還要簡單的建構,而且提供較佳的效能特性。
Shape 可讓您將圖形圖案繪製至螢幕。因為它們是衍生自 FrameworkElement 類別,所以 Shape 物件可以用於面板和大部分控制項內。
WPF 提供圖形和呈現服務的數個存取層。在最上層,Shape 物件十分容易使用,而且會提供許多有用的功能 (例如配置和事件處理)。WPF 會提供一些立即可用的圖案物件。所有圖案物件都是繼承自 Shape 類別。可用的圖案物件包括 Ellipse、Line、Path、Polygon、Polyline 和 Rectangle。
反之,Drawing 物件不是衍生自 FrameworkElement 類別,而且會提供較輕量 (Light-Weight) 的圖案、影像和文字呈現實作 (Implementation)。
Drawing 物件有四種型別:
GeometryDrawing:繪製圖案。
ImageDrawing:繪製影像。
GlyphRunDrawing:繪製文字。
DrawingGroup:繪製其他繪圖。您可以使用繪圖群組,將其他繪圖結合為單一複合繪圖。
GeometryDrawing 物件是用來呈現幾何內容。Geometry 類別以及從該類別衍生的具象類別 (如 CombinedGeometry、EllipseGeometry 和 PathGeometry) 提供呈現 2D 圖形的方法,以及提供點擊測試 (Hit-Test) 和裁剪 (Clipping) 支援。例如,幾何物件可以用來定義控制項區域,或定義要套用至影像的裁剪區域。幾何物件可以是簡單的區域,例如矩形和圓形,或從兩個以上幾何物件建立的複合區域。而透過結合 PathSegment 衍生物件 (如 ArcSegment、BezierSegment 和 QuadraticBezierSegment),可以建立更複雜的幾何區域。
表面上看來,Geometry 類別和 Shape 類別十分相似。這兩個類別都用於呈現 2D 圖形,而且也都具有從它們衍生的類似具象類別 (例如,EllipseGeometry 和 Ellipse)。然而,這兩組類別之間還是有很大的不同。其中一項是 Geometry 類別缺少 Shape 類別的一些功能 (如繪製它自己的能力)。若要繪製幾何物件,則必須使用另一個類別 (如 DrawingContext、Drawing 或 Path) (值得注意的是 Path 就是 Shape) 來執行繪製作業。呈現屬性 (如填滿、筆劃和筆劃粗細) 是位在可以繪製幾何物件的類別上,而圖案物件則包含這些屬性。其中一種分辨這項差異的方式是,幾何物件會定義區域 (例如圓形),而圖案物件則會定義區域、定義填滿該區域並為該區域加上外框的方式,並參與配置系統。
因為 Shape 物件是衍生自 FrameworkElement 類別,所以在應用程式中使用它們會明顯增加記憶體的耗用。如果確實不需要圖形內容的 FrameworkElement 功能,請考慮使用較輕量的 Drawing 物件。
StreamGeometry 物件
StreamGeometry 物件是 PathGeometry 的輕量替代方式,用於建立幾何圖案。當您需要描述複雜幾何時,請使用 StreamGeometry。StreamGeometry 已最佳化,適合用來處理許多 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 物件的詳細資訊,請參閱 HOW TO:使用 StreamGeometry 建立圖案。
DrawingVisual 物件
DrawingVisual 物件為輕量繪圖類別,可用於呈現圖案、影像或文字。此類別因為不提供配置或事件處理,所以視為輕量類別,而配置或事件處理卻可改善其效能。基於這個理由,繪圖適合用於背景或美工圖案。如需詳細資訊,請參閱使用 DrawingVisual 物件。
影像
WPF 影像處理明顯改善了舊版 Windows 中的影像處理功能。影像處理功能 (如在通用控制項上顯示點陣圖或使用影像) 主要是透過 Microsoft Windows 繪圖裝置介面 (Graphics Device Interface,GDI) 或 Microsoft Windows GDI+ 應用程式發展介面 (Application Programming Interface,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 物件 (如 DrawingBrush 和 VisualBrush) 的呈現內容。在內容和場景中的 TileBrush 使用都未變更的靜態情況下,這樣有其意義,因為可以節省視訊記憶體。但是在下列情況下則不具意義:以非靜態的方式使用具有靜態內容的 TileBrush (例如,當靜態 DrawingBrush 或 VisualBrush 對應至旋轉立體物件的表面時)。WPF 的預設行為是即使每個畫面格之 DrawingBrush 或 VisualBrush 的整個內容都未變更,仍然會重新呈現該內容。
藉由將 RenderOptions 物件的 CachingHint 屬性設定為 Cache,則可以使用並排顯示之筆刷物件的快取版本來提高效能。
CacheInvalidationThresholdMinimum 和 CacheInvalidationThresholdMaximum 屬性值是相對大小值,可以判斷因縮放比例變更而應該重新產生 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);