毛玻璃在UWP很简单,不会和WPF那样伤性能。

这是最近的博客,里面有很多 UWP 相关
博客在 lindexi.oschina.io 如果发现文章中存在错误,欢迎告诉我

本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃。

win10 UWP
访问网页

毛玻璃可以使用 win2D 方法,也可以使用 Compositor 。

win10 uwp
关联文件

使用 win2d 得到软件内控件毛玻璃,而使用 Compositor 可以获得窗口毛玻璃。

win10 uwp url
encode

先来说下如何使用 Compositor
做窗口毛玻璃,感觉小伙伴感兴趣的是窗口毛玻璃。

C#
解析数学函数

Compositor 创建毛玻璃

先写最简单的页面,只有一个 Grid, 给他名称
GlassHost,这个控件用于显示毛玻璃

            <Grid x:Name="GlassHost"></Grid>

然后在构造函数使用InitializeFrostedGlass,这个函数用于在一个控件显示毛玻璃

        public MainPage()
        {
            InitializeComponent();
            InitializeFrostedGlass(GlassHost);
        }

        private void InitializeFrostedGlass(UIElement glassHost)
        {
            Visual hostVisual = ElementCompositionPreview.GetElementVisual(glassHost);
            Compositor compositor = hostVisual.Compositor;
            var backdropBrush = compositor.CreateHostBackdropBrush();
            var glassVisual = compositor.CreateSpriteVisual();
            glassVisual.Brush = backdropBrush;
            ElementCompositionPreview.SetElementChildVisual(glassHost, glassVisual);
            var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
            bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);
            glassVisual.StartAnimation("Size", bindSizeAnimation);
        }

这样就可以看到毛玻璃效果

韦德国际1946 1

这个代码是从 http://www.jianshu.com/p/3b49fd3d7edb 复制的

大概解释一下, compositor.CreateHostBackdropBrush() 获得
创建之前绘制窗口后面视觉效果的区域,然后把他添加到Grid就可以了。

但是模糊的玻璃可以看不到里面控件,于是就把控件放在一个Grid
的最前,这样看起来背景就是毛玻璃

      <Grid > 最外层的 Grid 不要设置 BackGround 
        <Grid x:Name="GlassHost"></Grid> 把他放在最前
        <ListView ItemsSource="{x:Bind AvaloniaCol}" IsItemClickEnabled="True" ItemClick="ListViewBase_OnItemClick" >
            <ListView.ItemTemplate>
                <DataTemplate>
                   <Grid Background="#FFFFFF" PointerPressed="UIElement_OnPointerPressed">
                        <TextBlock Text="{Binding}"></TextBlock>
                   </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Button Content="添加" Click="ButtonBase_OnClick"></Button> 可以看到按钮,是清晰的
    </Grid>

如何去掉标题栏,上面的博客也有说,于是我就不多说啦。

win10 uwp
获得元素绝对坐标

win2D

下面介绍使用 win2d 做毛玻璃

使用 win2D 方法,需要使用 Nuget 安装,如果速度太慢,推荐使用博客园的镜像

韦德国际1946 2

这个方法可以获得控件的毛玻璃,但是不可以获得窗口毛玻璃

韦德国际1946 3

接下来告诉大家如何做上图的效果。

但是可以看到,上面的图做了其他的,如拖动时显示后面的图片。为了显示最短的代码,让大家知道毛玻璃是如何做的,下面先来做效果。

第一步,获得显示的图片

参见:win10 uwp 截图
获取屏幕显示界面保存图片

于是在界面显示一个图片,界面的左边就是图片,右边就是毛玻璃。之所以需要获得图片的截图是因为毛玻璃需要输入源,于是界面代码如下

         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid Margin="10 10 10 10">
             必须把图片的路径修改为自己工程的路径,需要在工程存在图片
            <Image x:Name="Image" Source="Assets/2017年5月31日 210702.jpg" Stretch="UniformToFill" />
        </Grid>
        <Grid Grid.Column="1" Margin="10 10 10 10">
            <xaml:CanvasControl x:Name="Canvas" CreateResources="Canvas_CreateResources" Draw="Canvas_Draw" />
        </Grid>

毛玻璃效果写在 CanvasControl ,
需要对显示截图,把图片做效果。然后把得到的效果显示

但是在什么时候截图?也就是什么时候才是截图最好的时候?

我认为可以在 CreateResources 事件进行截图,请看代码

         void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEventArgs args)
        {
            args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
        }

        async Task CreateResourcesAsync(CanvasControl sender)
        {
            // give it a little bit delay to ensure the image is load, ideally you want to Image.ImageOpened event instead
            await Task.Delay(200);  这是等待图片加载,因他发生在控件初始之后,而图片加载发生在图片控件初始的时候,但是图片加载需要时间,所以这里等待一下。我觉得这是比较差的方法

            using (var stream = new InMemoryRandomAccessStream())
            {
                // get the stream from the background image
                var target = new RenderTargetBitmap(); 这就是截图
                await target.RenderAsync(Image);

                var pixelBuffer = await target.GetPixelsAsync();
                var pixels = pixelBuffer.ToArray();

                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint) target.PixelWidth, (uint) target.PixelHeight, 96 如果 dpi 不是96 那么这里需要写实际的,为了简单,我就不写如何获得dpi, 96, pixels);

                await encoder.FlushAsync();
                stream.Seek(0);

                // load the stream into our bitmap
                _bitmap = await CanvasBitmap.LoadAsync(sender, stream);
            }
        }

第二步就是把图片进行效果,代码很少

         void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
        {
            using (var session = args.DrawingSession)
            {
                var blur = new GaussianBlurEffect
                {
                    BlurAmount = 50.0f, // increase this to make it more blurry or vise versa.
                    //Optimization = EffectOptimization.Balanced, // default value
                    //BorderMode = EffectBorderMode.Soft // default value
                    Source = _bitmap
                };

                session.DrawImage(blur, new Rect(0, 0, sender.ActualWidth, sender.ActualHeight),
                    new Rect(0, 0, _bitmap.SizeInPixels.Width, _bitmap.SizeInPixels.Height), 0.9f);
            }
        }

现在看起来就是

韦德国际1946 4

如果需要修改模糊,请把 BlurAmount 修改为你想要的

上面的代码就是主要的,接下来就是做上图的效果

首先xaml代码:

            <Grid x:Name="ImagePanel2" Width="356" Height="200" Margin="0,0,0,40" VerticalAlignment="Bottom">
            <Image x:Name="Image2" Source="Assets/2017年5月31日 210702.jpg" Stretch="UniformToFill" />
            <Grid x:Name="Overlay" ManipulationMode="TranslateX" ManipulationStarted="Overlay_ManipulationStarted" ManipulationDelta="Overlay_ManipulationDelta" ManipulationCompleted="Overlay_ManipulationCompleted" RenderTransformOrigin="0.5,0.5">
                <Grid.Clip>
                    <RectangleGeometry x:Name="Clip" Rect="0, 0, 356, 200" />
                </Grid.Clip>
                <Rectangle x:Name="WhiteMask" Fill="White" />
                <xaml:CanvasControl x:Name="Canvas" CreateResources="Canvas_CreateResources" Draw="Canvas_Draw" />
            </Grid>
        </Grid>

可以看到,这里引用 CanvasControl ,还有很多代码需要写在后面

         void Canvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEventArgs args)
        {
            args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
        }

        async Task CreateResourcesAsync(CanvasControl sender)
        {
            // give it a little bit delay to ensure the image is load, ideally you want to Image.ImageOpened event instead
            await Task.Delay(200);

            using (var stream = new InMemoryRandomAccessStream())
            {
                // get the stream from the background image
                var target = new RenderTargetBitmap();
                await target.RenderAsync(this.Image2);

                var pixelBuffer = await target.GetPixelsAsync();
                var pixels = pixelBuffer.ToArray();

                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint) target.PixelWidth, (uint) target.PixelHeight, 96, 96, pixels);

                await encoder.FlushAsync();
                stream.Seek(0);

                // load the stream into our bitmap
                _bitmap = await CanvasBitmap.LoadAsync(sender, stream);
            }
        }

        void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
        {
            using (var session = args.DrawingSession)
            {
                var blur = new GaussianBlurEffect
                {
                    BlurAmount = 50.0f, // increase this to make it more blurry or vise versa.
                    //Optimization = EffectOptimization.Balanced, // default value
                    //BorderMode = EffectBorderMode.Soft // default value
                    Source = _bitmap
                };

                session.DrawImage(blur, new Rect(0, 0, sender.ActualWidth, sender.ActualHeight),
                    new Rect(0, 0, _bitmap.SizeInPixels.Width, _bitmap.SizeInPixels.Height), 0.9f);
            }
        }

        void Overlay_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
        {
            // 重新设置 _x
            _x = (float) this.ImagePanel2.ActualWidth;
        }

        void Overlay_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
        {
            //获得当前的x,用于下面计算
            _x += (float) e.Delta.Translation.X;

            //如果当前的x超过了,或者已经最小
            if (_x > ImagePanel2.ActualWidth || _x < 0)
                return;

            //我们剪辑覆盖,用于显示下面的图片
            Clip.Rect = new Rect(0, 0, _x, this.ImagePanel2.ActualHeight);
        }

        void Overlay_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            // 重置剪辑显示完整的覆盖
            Clip.Rect = new Rect(0, 0, this.ImagePanel2.ActualWidth, this.ImagePanel2.ActualHeight);
        }

上面的代码就是获得图片,把图片使用 GaussianBlurEffect 得到毛玻璃

实际代码做的就是 如下面显示,做出毛玻璃效果,其他代码都是为了做刚才的图

        void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
        {
            using (var session = args.DrawingSession)
            {
                var blur = new GaussianBlurEffect
                {
                    BlurAmount = 50.0f, // increase this to make it more blurry or vise versa.
                    //Optimization = EffectOptimization.Balanced, // default value
                    //BorderMode = EffectBorderMode.Soft // default value
                    Source = _bitmap
                };

                session.DrawImage(blur, new Rect(0, 0, sender.ActualWidth, sender.ActualHeight),
                    new Rect(0, 0, _bitmap.SizeInPixels.Width, _bitmap.SizeInPixels.Height), 0.9f);
            }
        }

关于拖动使用裁剪显示后面的图,我就不多说了,实际代码看起来很多,但是不是很难,我就不说拉。

请看下面的效果,这就是不停修改 BlurAmount 得到。

韦德国际1946 5

代码很简单,所以我就不说。

win10 uwp
改变鼠标

最简单方法

当然,还有最简单的代码,只需要一句话,请看文档
Acrylic
material

因为不知道微软是否还更改,所以我就不写了。

为了说明代码的简单,我需要给个例子,上面那么长的代码,现在只需要一行

<Grid Background="{ThemeResource SystemControlAcrylicElementBrush}">

参见:https://stackoverflow.com/questions/31987817/how-to-make-frosted-glass-effect-in-windows-10-universal-app

http://microsoft.github.io/Win2D/html/N_Microsoft_Graphics_Canvas_Effects.htm

(UWP)应用窗口实现毛玻璃效果 –
简书

韦德国际1946 6
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0
国际许可协议
进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd
),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

win10 uwp
读写XML

C#
相对路径转绝对路径

创建不带BOM
的UTF8

win10 uwp
反射

win10 UWP
修改密码框文字水平

git
分支改名

WPF
拖动滚动

C#委托

C# AddRange
添加位置

C# 7.0

C#命令行解析工具

生成密码

C#枚举中使用Flags特性

产品经理——做一个自己的系统

git push 错误 hook
declined

WPF
设置输入只能英文

硬件分配

win10 UWP
发邮件

Latex
去掉行号

C#同步方法转异步

C#
转换类型和字符串

WPF
开发

C#判断文件属于文本或二进制

WPF 鼠标移动到列表上
显示列表图标

WPF
延迟加载

C# TextBlock
上标

UWP
分享用那个图标

C#
复制列表

C# 动态加载卸载
DLL

C# 解析 sln
文件

VisualStudio
扩展开发

自动机

C#
判断文件编码

C# 6.0 字符串 String
Interpolation

大文件的存储和备份

win10 uwp httpClient
登陆CSDN

win10 UWP
用Path画图

visual Studio
无法调试,提示程序跟踪已退出

WPF
资源冻结

C#判断文件是否被混淆

C#
通配符转正则

win10 UWP
单元测试

C#
搜索算法

win10 uwp HttpClient
post错误

win10 UWP ListView
模仿开始菜单

win10 UWP
蜘蛛网效果

win10 uwp 读取保存WriteableBitmap
、BitmapImage

win10 uwp
如何拖动一个TextBlock的文字到另一个TextBlock

win10 uwp
判断本地ip

Visual studio C# 代码使用
NotNull

本文说如何显示SVG

卷积神经网络全面解析

win10-uwp-用广告赚钱

win10-uwp-快捷键

win10 uwp 验证输入
自定义用户控件

win10 uwp
颜色转换

win10 uwp
选颜色

win10 uwp 起源Origin
含源代码

win10 uwp
获取按钮鼠标左键按下

win10 uwp
标题栏

win10 uwp 截图
获取屏幕显示界面保存图片

win10 uwp
多语言

win10 uwp
图标制作器

win10 uwp 右击选择
GridViewItem

win10 uwp
右击浮出窗在点击位置

win10 uwp
参考

win10 uwp
初始屏幕

win10 uwp
列表模板选择器

win10 uwp
修改CalendarDatePicker图标颜色

win10 uwp
从Type使用构造

win10 uwp
hashcash

win10 uwp
MVVM入门

win10 UWP
圆形等待

win10 UWP
全屏

win10 UWP 使用
MD5算法

win10 UWP
九幽数据分析

win10 UWP
MvvmLight入门

win10 UWP Markdown
含源代码

sublime Text
正则替换

git镜像仓库

WPF
只允许打开一个实例

CSDN 阅读
源代码

win10 uwp
网络编程

win10 uwp
dataGrid

win10 uwp
读写csv

简单搭建自己的博客

正则表达式30分钟入门教程

控件

手机1520
win8.1升级win10

图论 Warshall 和Floyd
矩阵传递闭包

关于Host(主机)/)

俄罗斯方块

代码段

不使用数据结构反转栈

上传代码
CodePlex

三种方式设置特定设备UWP XAML
view

windows-10「设置」应用完整ms-settings快捷方式汇总

windows 10预览版升级win10 7月29
10240.16384

win10
安装Mpi

win10
uwp如何使用DataTemplate

win10 uwp
魔力鬼畜

win10 uwp
隐藏实时可视化

win10 uwp
隐私声明

win10 uwp
随着数字变化颜色控件

win10 uwp 车表盘
径向规

win10 uwp
读取文本GBK错误

win10 uwp
语音

win10 uwp
访问解决方案文件

win10 uwp 设置启动窗口大小
获取窗口大小

win10 uwp
获得焦点改变

win10 uwp
获得Slider拖动结束的值

win10 uwp 自定义控件
SplitViewItem

win10 uwp 绘图 Line
控件使用

win10 uwp
绑定静态属性

win10 uwp
绑定密码

win10 uwp
简单MasterDetail

win10 uwp
活动磁贴

win10 uwp
显示SVG

win10 uwp
无法附加到CoreCLR

win10 uwp
按下等待按钮

win10 uwp
拖动控件

win10 uwp
打电话

win10 uwp
打包第三方字体到应用

win10 uwp
手动锁Bitlocker

win10 uwp
弹起键盘不隐藏界面元素

win10 uwp
异步进度条

win10 uwp
应用转后台清理内存

win10 uwp
布局

win10 uwp
存放网络图片到本地

win10 uwp
如何让WebView标识win10手机

win10 uwp
圆角按钮

win10 uwp
动画

win10 uwp
判断文件存在

win10 uwp
切换主题

win10 uwp
分治法

win10 uwp
兴趣线

win10 uwp
入门

win10 uwp 修改Pivot Header
颜色

win10 uwp
保存用户选择文件夹

win10 uwp
使用油墨输入

win10 uwp
从StorageFile获取文件大小

win10 uwp
九幽图床

win10 uwp 上传Nuget
让别人用我们的库

win10 uwp
win2d

win10 uwp
smms图床

win10 uwp
json

win10 uwp iot

win10 uwp
Window.Current.Dispatcher中Current为null

win10 uwp
Markdown

win10 uwp
InkCanvas控件数据绑定

win10 uwp ContentDialog
点确定不关闭

win10 uwp BadgeLogo
颜色

win10 uwp App-to-app communication
应用通信

win10
edge扩展

win10 UWP
标题栏后退

win10 UWP
应用设置

win10 UWP 剪贴板
Clipboard

win10 UWP
九幽登录

win10 UWP
button

win10 UWP
RSS阅读器

win10 UWP MessageDialog 和
ContentDialog

win10 UWP
Hmac

win10 UWP Controls by
function

win 10 UWP
标签

visual studio 2015 warning
MSB3246

resharper
自定义代码片

git
合并两个仓库

git rebase

default

Xamarin Forms
进度条控件

Win10 UWP Intro to controls and
events

WPF
绑定密码

WPF
popup置顶

WPF
checkbox文字下掉

Visual studio
创建项目失败vstemplate

Visual Studio
自定义项目模板

Latex
论文elsevier,手把手如何用Latex写论文

C#将dll打包到程序中

C# 设计模式
责任链

resharper
自定义代码片

相关文章