[C#][WPF] 使用BlurEffect輕鬆達成高斯模糊效果
之前因為專案需求,需要實作類似Windows Aero中的「毛玻璃效果(Aero Glass)」
(圖:Aero Glass, 圖片來源: http://www.teebo.com/AeroGlassVB.htm)
我們可以簡單地分析一下,其實像這樣毛玻璃的效果就是將物件半透明後加入高斯模糊(Gausscian Blur)濾鏡。當然在WPF裡面來說,將物件半透明化絕對不會是問題,但高斯模糊呢?
在我還不知道有.NET 3.5有內建BlurEffect這個類別之前,我曾經嘗試花了好幾天試著去用PixelShader去自己撰寫一個Gausscian Blur的Shader。
結果寫了一天之後,發現自己寫Shader的功力頂多只寫得出左右鏡射之類的功能之後,就放棄輾轉上網搜尋已經寫好的Shader…更奇妙的是,其實在網路上高斯模糊的Shader其實有非常多種寫法及版本,而不同的演算法也會造成不同的效果,但是大部分的Pixel Shader都是跟VertexShader或C++寫在一起,版本也相當混亂。最後我還是沒能找到一個適合的高斯模糊Shader來套用,所以我最後決定……放棄。
就在我放棄之際,隨手Google了一下現有的Effect類別,這才讓我發現了這個BlurEffect(System.Windows.Media.Effects.BlurEffect)其實已經內建在.NET 裡面了(已哭…
簡介BlurEffect
所以今天要介紹的BlurEffect使用非常非常非常簡單,我們只要產生一個BlurEffect實體,依照你需要的模糊程度,簡單修改一下其Radius屬性,然後套用到所需物件的Effect屬性上,就大功告成了(比起PixelShader還真踏馬的簡單…)
而控制部分,BlurEffect的重點屬性有兩個,分別為:
屬性 | 說明 |
Radius | 取得或設定值,這個值指出柔邊效果之曲線的半徑。 |
RenderingBias | 取得或設定值,這個值指出系統在呈現效果時要強調速度還是品質。 |
實作
實際程式碼如下
1: /* 產生BlurEffect實體 */
2: BlurEffect m_BlurEffect = new BlurEffect();
3:
4: /* 套用到視覺物件上 */
5: UI_Image.Effect = m_BlurEffect;
6:
7: /* 指定BlurEffect的屬性 */
8: m_BlurEffect.RenderingBias = RenderingBias.Quality;
9: m_BlurEffect.Radius = 10;
而且這個Effect在XAML也可以使用呦,用法如下
1: <Image Height="Auto" HorizontalAlignment="Left" Name="UI_Image" Stretch="Fill" VerticalAlignment="Top" Width="Auto" Source="/BlurTest;component/Images/batman.jpg">
2: <Image.Effect>
3: <BlurEffect Radius="10" RenderingBias="Quality"/>
4: </Image.Effect>
5: </Image>
套用前
套用後

效果大概是這樣子,咱們的黑暗騎士就算模糊了還是一樣帥呢。
彈性修改
因為BlurEffect的兩種屬性都屬於DependecyProperty,所以我們在BlurEffect套用之後的任何時間點都可以對這兩項屬性作動態修改,想要模糊就模糊,想要清楚就清楚,想要模糊就模糊,想要清楚就清楚,想要模糊就…好的。
套用動畫
也因為這兩項屬性屬於DependencyProperty,所以我們可以套用Animation到這兩項屬性上,可以讓高斯模糊產生由清楚到模糊的一段動畫(類似鏡頭失焦的效果,反之逆向則為對焦的感覺)
1: BlurEffect m_BlurEffect = new BlurEffect();
2:
3: UI_Image.Effect = m_BlurEffect;
4: m_BlurEffect.RenderingBias = RenderingBias.Quality;
5:
6: DoubleAnimation m_DA = new DoubleAnimation();
7: m_DA.From = 0.0f;
8: m_DA.To = 50.0f;
9: m_DA.Duration = TimeSpan.FromMilliseconds(1000);
10: m_DA.EasingFunction = new CubicEase();
11: m_DA.AutoReverse = true;
12: m_DA.RepeatBehavior = RepeatBehavior.Forever;
13:
14: m_BlurEffect.BeginAnimation(BlurEffect.RadiusProperty, m_DA);
這樣子就完成了一個從失焦到對焦,在從對焦到失焦的動畫了喲,真的是比自己寫PixelShader簡單好用太多了。
沒有留言:
張貼留言