WPF繪製向量圖形模糊的問題
WPF預設提供了抗鋸齒功能,通過向外擴充套件的半透明邊緣來實現模糊化。由於WPF採用了裝置無關單位,當裝置DPI大於系統DPI時,可能會產生畫素自動擴充套件問題,這就導致線條自動向外擴充套件一個畫素,並且與邊緣相鄰的線條顏色變成了半透明,如下圖所示:
這種特性在繪製細線條的時候會導致一些我們所不期望的結果:顏色變淡,線條模糊,線條變粗。很多時候,我們是無法繪製一個畫素的清晰的線條的。對於這個問題,WPF給我們提供了幾種解決方案:
1、設定畫素對齊
對於系統內建的一些控制元件,通過設定SnapsToDevicePixels為true,可以非常方便的實現畫素對齊。
這個屬性是有繼承效果的,只要在父控制元件上設定了,其所有的子控制元件都是生效的。但它有時會出現改變視窗大小時線條消失的情況
2、設定對齊參考線
方法1只針對系統的內建的一些控制元件有效,但對於使用DrawingVisual等方式自繪的圖形則沒有效果。此時可以通過設定參考線解決這一問題。
簡單的示例如下:
void render(DrawingContext dc) { var pen = new Pen(Brushes.Black, 1); var d = pen.Thickness / 2; var guidelines = newGuidelineSet(new []{d}, new[]{d}); dc.PushGuidelineSet(guidelines); dc.DrawLine(pen, new Point(30, 10), new Point(30, 80)); dc.DrawLine(pen, new Point(50, 20), new Point(50, 80)); }
具體程式碼參見MSDN:Apply a GuidelineSet to a Drawing,也可以參看這篇文章WPF DrawingContext seems ignore SnapToDevicePixels
3、設定 RenderOptions.EdgeMode="Aliased"
前面的設定參考線方式效果較好,不過需要編寫較多的程式碼,並且只能適用於水平或垂直的線條。很多時候,我使用的是設定 RenderOptions.EdgeMode="Aliased"(如果在程式碼中則是使用this.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased)),
4、設定UseLayoutRounding="True"
這個是在WPF4後增加的一個選項,用來控制佈局舍入的,用來控制圖片模糊的效果非常好,用於控制控制元件的模糊效果也不錯的。不過也是對DrawingContext繪製的圖形沒有效果的。
小結:WPF的抗鋸齒效果在給我們帶來的很好的視覺效果的同時,也給我們帶來的不少困擾,本文就總結了幾種常見的解決方案,希望能對大家的工作帶來一點幫助。