1. 程式人生 > >Windows 10 應用建立模糊背景視窗的三種方法

Windows 10 應用建立模糊背景視窗的三種方法

原文 Windows 10 應用建立模糊背景視窗的三種方法

現代的作業系統中建立一張圖片的高斯模糊效果非常容易,不過如果要在視窗中獲得模糊支援就需要作業系統的原生支援了。iOS/Mac 和 Windows 系統都對此有支援。

本文將介紹三種建立模糊背景視窗的方法。有人可能喜歡稱之為毛玻璃視窗、亞克力視窗。


This post is written in multiple languages. Please select yours:

 

最早我是在 StackOverflow 上回答一位網友的提問時寫了一份非常長的答案,後來小夥伴建議我將答案改寫成部落格,於是我就改了。StackOverflow 上的答案在這裡:

colors - WPF: How to Style my form with Transparency levels - Stack Overflow

本文內容

三種建立模糊背景視窗的方法

Windows 10 上建立帶模糊背景的視窗有三種不同的方法,不過每一種都是既有好處又有壞處的:

  1. 呼叫 Win32 API —— SetWindowCompositionAttribute

    ,使用這種方式能夠獲得一個背景輕微透明的視窗。當然,如果需要模擬亞克力效果或者是 iOS/Mac 上的模糊效果就 gg 了。
    The image from my post

  2. 為視窗中的背景圖片新增 WPF 自帶的模糊效果 BlurEffect。這種方式你想獲得多大的模糊半徑就能獲得多大的模糊半徑,不過帶來的就是更高的效能損耗。同時,還得考慮在移動視窗的時候動態地去更新背景圖片並再次模糊。
    BlurEffect of WPF

  3. 使用 Fluent Design System 中的亞克力效果 —— AcrylicBrush。這絕對是 Windows 10 上獲得背景模糊效果中視覺效果最好,同時又最省效能的方法了。不過,這種方法只能在 UWP 應用中使用。
    The UWP AcrylicBrush from docs.microsoft.com


SetWindowCompositionAttribute API

SetWindowCompositionAttribute 並沒有那麼好呼叫,所以我為此寫了一個輔助類類封裝對背景模糊效果的呼叫。使用這個輔助類,你只需要使用一行程式碼就能開啟背景模糊效果。

可以在 XAML 程式碼中使用 interop:WindowBlur.IsEnabled="True"

<Window x:Class="Walterlv.Demo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:interop="clr-namespace:Walterlv.Demo.Interop" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" interop:WindowBlur.IsEnabled="True" Background="Transparent"> </Window> 

可以在 cs 程式碼中使用 WindowBlur.SetIsEnabled(this, true)

public class MainWindow : Window { public MainWindow() { InitializeComponent(); WindowBlur.SetIsEnabled(this, true); } } 

我為 WindowBlur 類準備了一個 GitHub Gist,在這裡:https://gist.github.com/walterlv/752669f389978440d344941a5fcd5b00。你只需要將程式碼全部複製到你的專案中即可開始使用。

當然,我還寫了一篇部落格專門講使用 SetWindowCompositionAttribute API 實現背景模糊效果:在 Windows 10 上為 WPF 視窗新增模糊特效(就像開始選單和操作中心那樣)

WPF BlurEffect

WPF 的 UIElement 都有 Effect 屬性,將其設定為 BlurEffect 即可獲得控制元件的高斯模糊效果。

<Window x:Class="MejirdrituTeWarqoudear.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" AllowsTransparency="True" WindowStyle="None" Width="540" Height="360"> <Grid> <Image Source="YourImageFile.jpg" Stretch="Fill" Margin="-60"> <Image.Effect> <BlurEffect KernelType="Gaussian" Radius="60" /> </Image.Effect> </Image> <Border CornerRadius="60" Margin="30" Background="#7F000000"> <TextBlock Foreground="White" FontSize="20" FontWeight="Light" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"> <Run Text="Hello World" FontSize="48"/> <LineBreak/> <Run Text="walterlv.github.io"/> </TextBlock> </Border> </Grid> </Window> 

特別注意:此方法有嚴重地效能問題

如果你的視窗是一個異形視窗,例如是具有圓角的矩形,那麼你需要額外為控制元件設定 RectangleGeometry 來裁剪控制元件。

Rounded Rectangle

<Window x:Class="MejirdrituTeWarqoudear.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="540" Height="360"> <Grid> <Grid.Clip> <RectangleGeometry RadiusX="60" RadiusY="60" Rect="30 30 480 300" /> </Grid.Clip> <Image Source="High+Sierra.jpg" Stretch="Fill" Margin="-60"> <Image.Effect> <BlurEffect KernelType="Gaussian" Radius="60" /> </Image.Effect> </Image> <Border Background="#7F000000"> <TextBlock Foreground="White" FontSize="20" FontWeight="Light" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"> <Run Text="Hello World" FontSize="48"/> <LineBreak/> <Run Text="walterlv.github.io"/> </TextBlock> </Border> </Grid> </Window> 

如果是圓形視窗,我另外寫了一篇文章來說明進行圓形裁剪:WPF 中使用附加屬性,將任意 UI 元素或控制元件裁剪成圓形(橢圓)

UWP AcyclicBrush

微軟的官方文件 Acrylic material - UWP app developer - Microsoft Docs 講解了如何使用亞克力效果。

本文會經常更新,請閱讀原文: https://walterlv.com/post/create-blur-background-window.html ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。