2018-8-10-win10-uwp-毛玻璃
title | author | date | CreateTime | categories |
---|---|---|---|---|
win10 uwp 毛玻璃
|
lindexi
|
2018-08-10 19:16:50 +0800
|
2018-2-13 17:23:3 +0800
|
UWP win2d
|
毛玻璃在UWP很简单,不会和WPF那样伤性能。
本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃。
毛玻璃可以使用 win2D 方法,也可以使用 Compositor 。
使用 win2d 得到软件内控件毛玻璃,而使用 Compositor 可以获得窗口毛玻璃。
先来说下如何使用 Compositor 做窗口毛玻璃,感觉小伙伴感兴趣的是窗口毛玻璃。
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);
}
这样就可以看到毛玻璃效果
这个代码是从 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>
如何去掉标题栏,上面的博客也有说,于是我就不多说啦。
win2D
下面介绍使用 win2d 做毛玻璃
使用 win2D 方法,需要使用 Nuget 安装,如果速度太慢,推荐使用博客园的镜像
这个方法可以获得控件的毛玻璃,但是不可以获得窗口毛玻璃
接下来告诉大家如何做上图的效果。
但是可以看到,上面的图做了其他的,如拖动时显示后面的图片。为了显示最短的代码,让大家知道毛玻璃是如何做的,下面先来做效果。
第一步,获得显示的图片
于是在界面显示一个图片,界面的左边就是图片,右边就是毛玻璃。之所以需要获得图片的截图是因为毛玻璃需要输入源,于是界面代码如下
<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);
}
}
现在看起来就是
如果需要修改模糊,请把 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 得到。
代码很简单,所以我就不说。
最简单方法
当然,还有最简单的代码,只需要一句话,请看文档
Acrylic material
因为不知道微软是否还更改,所以我就不写了。
为了说明代码的简单,我需要给个例子,上面那么长的代码,现在只需要一行
<Grid Background="{ThemeResource SystemControlAcrylicElementBrush}">
关于FDS请看win10 uwp Fluent Design System 实践
http://microsoft.github.io/Win2D/html/N_Microsoft_Graphics_Canvas_Effects.htm
2018-8-10-win10-uwp-毛玻璃的更多相关文章
- win10 uwp 毛玻璃
毛玻璃在UWP很简单,不会和WPF那样伤性能. 本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃. 毛玻璃可以使用 win2D 方法,也可以使用 Compositor . 使用 win2d 得 ...
- win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl
本文来告诉大家 CanvasVirtualControl ,在什么时候使用这个控件. 在之前的入门教程win10 uwp win2d 入门 看这一篇就够了我直接用的是CanvasControl,实际上 ...
- win10 uwp 使用 Microsoft.Graph 发送邮件
在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...
- Win10 UWP开发实现Bing翻译
微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...
- Win10/UWP开发—使用Cortana语音与App后台Service交互
上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...
- Win10 UWP应用发布流程
简介 Win10 UWP应用作为和Win8.1 UAP应用不同的一种新应用形式,其上传至Windows应用商店的流程也有了一些改变. 这篇博文记录了我们发布一款Win10 UWP应用的基本流程,希望为 ...
- win10 uwp 列表模板选择器
本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...
- win10 uwp 获得元素绝对坐标
有时候需要获得一个元素,相对窗口的坐标,在修改他的位置可以使用. 那么 UWP 如何获得元素坐标? 我提供了一个方法,可以获得元素的坐标. 首先需要获得元素,如果没有获得元素,那么如何得到他的坐标? ...
- win10 uwp 读取保存WriteableBitmap 、BitmapImage
我们在UWP,经常使用的图片,数据结构就是 BitmapImage 和 WriteableBitmap.关于 BitmapImage 和 WriteableBitmap 区别,我就不在这里说.主要说的 ...
- 【广告】win10 uwp 水印图床 含代码
本文主要是广告我的软件. 图床可以加速大家写博客上传图片的时间,通过简化我们的操作来得到加速. 在写博客的时候,我们发现,我们需要上传一张图片,需要先打开图片,然后选择本地图片,然后上传. 但是我经常 ...
随机推荐
- 线程数设置和CPU数的关系
一般说来,大家认为线程池的大小经验值应该这样设置:(其中N为CPU的个数) 如果是CPU密集型应用,则线程池大小设置为N+1 如果是IO密集型应用,则线程池大小设置为2N+1(因为io读数据或者缓存的 ...
- flask之显示当地时间
一:在网页上显示时间 flask-moment 程序扩展可以实现 pip install flask-moment # 未完待续
- docker中pull镜像,报错 pull access denied for ubantu, repository does not exist or may require 'docker login'
报错说明:拒绝获取ubantu, 仓库不存在或者需要登录docker 1.先尝试注册docker 2.在拉镜像前,先登录docker, 命令:docker login 3.然后执行 docker ...
- 前端每日实战:2# 视频演示如何用纯 CSS 创作一个矩形旋转 loader 特效
效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/vjLQMM 可交互视频教程 此视频是可以交 ...
- mac的jvm调优工具
安装好JDK之后调优工具所在位置为: /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jvisualvm j ...
- Linux之虚拟机里的REHL7的IP
RHEL7最小化安装之后(桥接模式),我们查看本机IP, ip addr ifconfig 我们要修改配置文件 找到目录 找到文件,用vi编辑器打开修改配置文件 保存退出后,需要重启网络服务 只有我们 ...
- NuGet-Doc:NuGet.Server
ylbtech-NuGet-Doc:NuGet.Server 1.返回顶部 1. NuGet.Server 2018/03/13 NuGet.Server 是由 .NET Foundation 提供的 ...
- linux安装.net core3.0
https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-package-manager-centos7 更新资料库 sudo rpm -U ...
- php面向对象重的抽象类,接口类与静态
static 静态 <?php class ren { public $name; public static $sex; static function shao() { echo " ...
- linux新建用户并修改提示符
1 新建用户 # useradd –d /home/ap/testapp -m testapp 此命令创建了一个用户testapp ,其中-d和-m选项用来为登录名testapp 产生一个主目录/ho ...