[UWP]组合CompositionBrush并使用BlendEffect
1. 什么是BlendEffect
上一篇文章介绍了CompositionLinearGradientBrush的基本用法, 这篇文章再结合BlendEffec介绍一些更复杂的玩法。
Microsoft.Graphics.Canvas.Effects命名空间下的BlendEffect 用于组合两张图片(分别是作为输入源的Background和Foreground),它包含多种模式,如下图所示:

其中最简单的是Screen模式,它的计算公式如下

看起来有点复杂, 我的理解是它相当于色轮中Background和Foreground之间拉直线,在直线的中间点的颜色,如下面这张图,红色和蓝色组合成为紫色:

2. 组合CompositionBrush并使用BlendEffect
许多 CompositionBrushes 使用其他 CompositionBrushes 作为输入。 例如,使用 SetSourceParameter 方法可以将其他 CompositionBrush 设为 CompositionEffectBrush 的输入。这是CompositionBrush最好玩的地方之一。下面的例子介绍了怎么使用BlendEffect创建CompositionBrush。
首先创建两个CompositionLinearGradientBrush:
var foregroundBrush = compositor.CreateLinearGradientBrush();
foregroundBrush.StartPoint = Vector2.Zero;
foregroundBrush.EndPoint = new Vector2(1.0f);
var redGradientStop = compositor.CreateColorGradientStop();
redGradientStop.Offset = 0f;
redGradientStop.Color = Color.FromArgb(255, 255, 0, 0);
var yellowGradientStop = compositor.CreateColorGradientStop();
yellowGradientStop.Offset = 1f;
yellowGradientStop.Color = Color.FromArgb(255, 0, 178, 255);
foregroundBrush.ColorStops.Add(redGradientStop);
foregroundBrush.ColorStops.Add(yellowGradientStop);
var backgroundBrush = compositor.CreateLinearGradientBrush();
backgroundBrush.StartPoint = new Vector2(0, 1f);
backgroundBrush.EndPoint = new Vector2(1f, 0);
var blueGradientStop = compositor.CreateColorGradientStop();
blueGradientStop.Offset = 0f;
blueGradientStop.Color = Color.FromArgb(255, 0, 0, 255);
var greenGradientStop = compositor.CreateColorGradientStop();
greenGradientStop.Offset = 1f;
greenGradientStop.Color = Color.FromArgb(255, 0, 255, 0);
backgroundBrush.ColorStops.Add(blueGradientStop);
backgroundBrush.ColorStops.Add(greenGradientStop);
它们的效果分别如下面两张图片所示:


接下来创建BlendEffect,并将Foreground和Background设置为CompositionEffectSourceParameter
var blendEffect = new BlendEffect()
{
Mode = BlendEffectMode.Screen,
Foreground = new CompositionEffectSourceParameter("Main"),
Background = new CompositionEffectSourceParameter("Tint"),
};
使用BlendEffect创建Brush,并用SetSourceParameter设置它的Foreground和Background。
var effectFactory = compositor.CreateEffectFactory(blendEffect);
var blendEffectBrush = effectFactory.CreateBrush();
blendEffectBrush.SetSourceParameter("Main", foregroundBrush);
blendEffectBrush.SetSourceParameter("Tint", backgroundBrush);
最后就是一般的使用这个blendEffectBrush的代码:
//创建SpriteVisual并设置Brush
var spriteVisual = compositor.CreateSpriteVisual();
spriteVisual.Brush = blendEffectBrush;
//将自定义 SpriteVisual 设置为元素的可视化树的最后一个子元素。
ElementCompositionPreview.SetElementChildVisual(Gradient, spriteVisual);
最终运行效果如下:

3. 创建动画
和上一篇文章一样,我也把这篇文章用到的技术用在了一个番茄钟应用里,,简单地使用ColorKeyFrameAnimation和ScalarKeyFrameAnimation制作动画:
private void StartOffsetAnimation(CompositionColorGradientStop gradientOffset, float offset)
{
var offsetAnimation = _compositor.CreateScalarKeyFrameAnimation();
offsetAnimation.Duration = TimeSpan.FromSeconds(1);
offsetAnimation.InsertKeyFrame(1.0f, offset);
gradientOffset.StartAnimation(nameof(CompositionColorGradientStop.Offset), offsetAnimation);
}
private void StartColorAnimation(CompositionColorGradientStop gradientOffset, Color color)
{
var colorAnimation = _compositor.CreateColorKeyFrameAnimation();
colorAnimation.Duration = TimeSpan.FromSeconds(2);
colorAnimation.Direction = Windows.UI.Composition.AnimationDirection.Alternate;
colorAnimation.InsertKeyFrame(1.0f, color);
gradientOffset.StartAnimation(nameof(CompositionColorGradientStop.Color), colorAnimation);
}
完整代码在这里,具体运行效果如下:

4. 结语
上面的动画可以安装我的番茄钟应用试玩一下,安装地址:
这篇文章的动画和代码都参考了JustinLiu的代码,感谢他的分享。
使用XAML画笔难以做到这种多向渐变的效果,这都多亏了UWP提供了BlendEffect这个好玩的东西。BlendEffect还有很多其它好玩的模式,大家有空可以多多尝试。
参考
合成画笔 - Windows UWP applications _ Microsoft Docs
源码
OnePomodoro_GradientsWithBlend.xaml.cs at master
[UWP]组合CompositionBrush并使用BlendEffect的更多相关文章
- [UWP]CompositionLinearGradientBrush加BlendEffect,双倍的快乐
原文:[UWP]CompositionLinearGradientBrush加BlendEffect,双倍的快乐 1. 什么是BlendEffect# 上一篇文章介绍了CompositionLinea ...
- UWP 响应键盘组合快捷键
方法1:响应Ctrl+?快捷键 首先在load事件或者keydown事件内注册事件 public MainPage() { this.InitializeComponent(); // Registe ...
- [UWP]用Win2D和CompositionAPI实现文字的发光效果,并制作动画
1. 成果 献祭了周末的晚上,成功召唤出了上面的番茄钟.正当我在感慨"不愧是Shadow大人,这难道就是传说中的五彩斑斓的黑?" "那才不是什么阴影效果,那是发光效果.& ...
- [UWP]抄抄《CSS 故障艺术》的动画
1. 前言 什么是故障艺术(Glitch Art 风)?我们熟知的抖音的 LOGO 正是故障艺术其中一种表现形式.它有一种魔幻的感觉,看起来具有闪烁.震动的效果,很吸引人眼球.故障艺术它模拟了画面信号 ...
- New UWP Community Toolkit - XAML Brushes
概述 上一篇 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾.接下来会针对每个重要更新,结合 SDK 源代码和调用代码详细讲解. 本篇我们 ...
- [UWP]使用AlphaMaskEffect提升故障艺术动画的性能(顺便介绍怎么使用性能探测器分析UWP程序)
前几天发布了抄抄<CSS 故障艺术>的动画这篇文章,在这篇文章里介绍了如何使用Win2D绘制文字然后配合BlendEffect制作故障艺术的动画.本来打算就这样收手不玩这个动画了,但后来又 ...
- MVVM框架从WPF移植到UWP遇到的问题和解决方法
MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...
- UWP简单示例(三):快速开发2D游戏引擎
准备 IDE:VisualStudio 2015 Language:VB.NET/C# 图形API:Win2D MSDN教程:UWP游戏开发 游戏开发涉及哪些技术? 游戏开发是一门复杂的艺术,编码方面 ...
- 【uwp】浅谈China Daily 中划词翻译的实现
学习uwp开发也有一段时间了,最近上架了一个小应用(China Daily),现在准备将开发中所学到的一些东西拿出来跟大家分享交流一下. 先给出应用的下载链接:China Daily , 感兴趣的童鞋 ...
随机推荐
- RDD基本操作之Action
Action介绍 在RDD上计算出来一个结果 把结果返回给driver program或保存在文件系统,count(),save 常用的Action reduce() 接收一个函数,作用在RDD两个类 ...
- 为什么一个标准的反相器中 P 管的宽长比要比 N 管的大呢?
和载流子有关.P 管是空穴导电,而 N 管是电子导电,电子的迁移率大于空穴.所以在同样的电场下,N 管的电流要大于 P 管,因此要增大 P 管的宽长比,使之对称,这样才能使得两者上升下降时间相等.高低 ...
- 10.Django基础八之cookie和session
一 会话跟踪 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而10086服务人员就是服务器 ...
- Robot Framework自定义测试库的作用域的理解
robot framework中,强大的测试库api支持,用户可根据实际需求定义测试库,导入后可使用自定义库中相应的关键字. 当自定义的测试库是类库,则需要考虑一个问题:类实例.用类实现的库可以有内部 ...
- QT两个窗口相互切换
信号(signals)与槽(slots)是QT重要机制,例子使用了C++11 lambda表达式进行了信号与槽的连接. 实现两个窗口通过点击按钮完成互相切换,注意子窗口只能发送信号,不能处理,所有信号 ...
- ajax跨域访问数据
通过json发送和接受数据,数据以json的格式在服务器端和前台进行传递,什么是json数据?这里就不进行详细阐述,轻自行百度解决. 在html5 中利用ajax 异步请求时,会遇到跨域的问题,如果域 ...
- 玩转 SpringBoot 2 之整合 JWT 下篇
前言 在<玩转 SpringBoot 2 之整合 JWT 上篇> 中介绍了关于 JWT 相关概念和JWT 基本使用的操作方式.本文为 SpringBoot 整合 JWT 的下篇,通过解决 ...
- 利用百度云接口实现车牌识别·python
一个小需求---实现车牌识别. 目前有两个想法 1. 调云在线的接口或者使用SDK做开发(配置环境和变异第三方库麻烦,当然使用python可以避免这些问题) 2. 自己实现车牌识别算法(复杂) 一开始 ...
- java实现有道翻译爬虫
我的博文地址 https://www.cnblogs.com/lingdurebing/p/11618902.html 使用的库 1.commons-codec 主要是为了加密,可以直接用java原生 ...
- python win32com 读取带密码的excel
之前用到的win32com读取带密码excel的相关内容,今天刚好准备整理下,突然发现方法又不灵了. 以下为错误示范: # 已知excel密码去除 def del_password(filename, ...