WPF 使用GDI+提取图片主色调并生成Mica材质特效背景
先看效果,在浅色模式下:



在深色模式下:



P.S. 此算法只是尽可能地接近Windows Mica效果,并非实际实现;主色调提取算法只能确保在绝大多数情况下适用。
测试项目在Github上开源:
TwilightLemon/MicaImageTest: WPF 使用GDI+提取图片主色调并生成Mica材质特效背景
一、简要原理和设计
1.1 Mica效果
Mica效果是Windows 11的一个新特性,旨在为应用程序提供一种更柔和的背景效果。它通过使用桌面壁纸的颜色和纹理来创建一个静态的模糊背景效果。一个大致的模拟过程如下:
- 根据颜色模式(浅色或深色)来调整图像对比度
- 增加一个白色/黑色的遮罩层
- 大半径 高斯模糊处理
在仓库代码中给出了所有组件的实现,如果你想调整效果,可以修改以下几个值:
1 public static void ApplyMicaEffect(this Bitmap bitmap,bool isDarkmode)
2 {
3 bitmap.AdjustContrast(isDarkmode?-1:-20);//Light Mode通常需要一个更高的对比度
4 bitmap.AddMask(isDarkmode);//添加遮罩层
5 bitmap.ScaleImage(2);//放大图像(原始图像一般为500x500)以提高输出图像质量
6 var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
7 bitmap.GaussianBlur(ref rect, 80f, false);//按需要调整模糊半径
8 }
1.2 主色调提取与微调
从原始图像中提取主色调,主要过程如下:
- 像素采样和颜色量化便于统计
- 过滤过黑或过白的颜色值(我们会在调整步骤单独处理)
- 根据HSL的饱和度和亮度来计算权重,
- 饱和度越高,权重越大
- 亮度稳定(我们定为0.6),权重越大
- 选择权重最大的颜色均值作为主色调
之后为了适配UI,保证亮度、饱和度适合用于呈现内容,还要对颜色进行微调:
- 将颜色转为HSL空间
- 根据颜色模式调节亮度
- 分层调整饱和度,一般来说暗色模式的对比度比亮色模式高
- 对特定色相区间(红/绿/蓝/黄)进行差异化调整
最后计算焦点颜色(FocusAccentColor)只需要根据颜色模式调整亮度即可。
二、使用方法
将代码仓库中的ImageHelper.cs添加到项目,然后在需要的地方调用Bitmap的扩展方法来处理图像。以下是一个简单的示例:
首先开启项目允许使用UnSafe代码:
<PropertyGroup>
<!-- 允许使用UnSafe代码 -->
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
导入本地图像文件,计算主色调、焦点色调并应用Mica效果背景:
var image=new BitmapImage(new Uri(ImagePath)); SelectedImg = image; var bitmap = image.ToBitmap(); //major color var majorColor = bitmap.GetMajorColor().AdjustColor(IsDarkMode); var focusColor = majorColor.ApplyColorMode(IsDarkMode); App.Current.Resources["AccentColor"] = new SolidColorBrush(majorColor); App.Current.Resources["FocusedAccentColor"] = new SolidColorBrush(focusColor); //background bitmap.ApplyMicaEffect(IsDarkMode); BackgroundImg = bitmap.ToBitmapImage();
其中,SelectedImg和BackgroundImg是绑定到UI的BitmapImage类型属性,IsDarkMode是指示当前颜色模式的布尔值。
三、注意事项
- 处理大图像时可能会导致性能下降,建议使用较小的图像或在后台线程中处理。
- 如果高斯模糊组件报错,请确保Nuget包
System.Drawing.Common的版本为8.0.1,因为代码中使用了反射获取Bitmap内部的句柄。 - 你可能需要根据实际情况调整模糊半径和对比度等参数,以获得最佳效果。
- 库中实现可能并非最佳写法,如果有更好的方法可以提交PR或者评论区见。
最后附上ImageHelper.cs的完整代码:
View Code

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名TwilightLemon,不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

浙公网安备 33010602011771号