[UWP]使用Win2D的BorderEffect实现图片的平铺功能
1. WPF有,而UWP没有的图片平铺功能
在WPF中只要将ImageSource的TileMode属性设置为Tile即可实现图片的平铺,具体可见WPF的这些文档:
ImageBrush 类 (System.Windows.Media) _ Microsoft Docs
TileBrush 类 (System.Windows.Media) _ Microsoft Docs
TileBrush.TileMode 属性 (System.Windows.Media) _ Microsoft Docs

WPF图片平铺功能我几乎没用过,只是作为基础中的基础知识记住了用法。我以为那么基础的功能在UWP肯定有,根本不用怀疑,所以当我在UWP中发现这么基础的东西居然没有时真的吓了一跳。

上图左面是WPF版本的TileBrush,右边是UWP版本,可以看到UWP版本功能少了一大半。
这么小的一个类,我觉得没必要在这里做简化吧。幸好图片平铺可以使用Win2D里的BorderEffect实现。

2. UWP中的图片平铺功能
<Grid>
<Rectangle x:Name="Background" />
</Grid>
假设有以上的XAML,要在名为Background的元素上应用合成画笔,首先引用Win2D.uwp nuget包,然后参考官方文档中 合成画笔 的部分使用图片创建一个合成画笔:
var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
var imageBrush = compositor.CreateSurfaceBrush();
var loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///110Strawberry.png"));
imageBrush.Surface = loadedSurface;
imageBrush.Stretch = CompositionStretch.None;
现在就差创建一个SpriteVisual并把它应用到Background的VisualTree上了,顺便一提,是这张图片:

不过要实现平铺功能还需要创建一个BorderEffect:
var borderEffect = new BorderEffect
{
Source = new CompositionEffectSourceParameter("source")
};
var effectFactory = compositor.CreateEffectFactory(borderEffect);
var effectBrush = effectFactory.CreateBrush();
effectBrush.SetSourceParameter("source", imageBrush);
var sprite = compositor.CreateSpriteVisual();
sprite.Brush = effectBrush;
var backgroundVisual = ElementCompositionPreview.GetElementVisual(Background);
var bindSizeAnimation = compositor.CreateExpressionAnimation("backgroundVisual.Size");
bindSizeAnimation.SetReferenceParameter("backgroundVisual", backgroundVisual);
sprite.StartAnimation("Size", bindSizeAnimation);
ElementCompositionPreview.SetElementChildVisual(Background, sprite);
总之BorderEffect以imageBrush为Source,其它都保留默认值,将它它应用到Background的VisualTree上后效果如下:

这还不是我想要的平铺效果。这是因为这时候ExtendX和ExtendY保持默认值的Clamp,这个类型会让BorderEffect重复图像边缘的属性。如果要实现我想要的平铺需要将这两个属性设置为Wrap:
borderEffect.ExtendX = CanvasEdgeBehavior.Wrap;
borderEffect.ExtendY = CanvasEdgeBehavior.Wrap;

居然不是从左上角开始平铺的,和我的想法还是有出入,不过这种细节就算了。顺便一提ExtendX和ExtendY还可以设置为Mirror,效果如下:

3. 绑定Size
var backgroundVisual = ElementCompositionPreview.GetElementVisual(Background);
var bindSizeAnimation = compositor.CreateExpressionAnimation("backgroundVisual.Size");
bindSizeAnimation.SetReferenceParameter("backgroundVisual", backgroundVisual);
sprite.StartAnimation("Size", bindSizeAnimation);
最后顺便提一下,上面的代码中有这么一段代码没介绍到,这是用来动态地设置SpriteVisual的尺寸。ExpressionAnimation有一直运行和永不停止这两个特性,创建ExpressionAnimation并在SpriteVisual上运行动画,实际上将SpriteVisual的Size永远地绑定为backgroundVisual 的Size的值。其实简单地订阅SizeChanged事件也能达到这个效果,代码好像还少些。
4. 结语
这么简单的功能居然都要这么多代码,或者有更简单的实现?不过凡事都有要辩证地看,幸好它这么复杂,又让我水了一篇博客。
Stack Overflow有给出其它的方案,可以参考一下。
5. 参考
Border effect - Win32 apps _ Microsoft Docs
合成画笔 - Windows UWP applications _ Microsoft Docs
【Win2D】【译】Win2D 快速入门 - h82258652 - 博客园
基于关系的动画 - Windows UWP applications Microsoft Docs
c# - UWP - How to tile a background image - Stack Overflow
[UWP]使用Win2D的BorderEffect实现图片的平铺功能的更多相关文章
- Android 背景图片重复平铺
有时候我们需要将一个图片横向或者纵向的平铺(重复循环),这个时候我们需要创建一个xml文件,如下: <?xml version ="1.0" encoding =" ...
- ios 缩放图片(平铺)
//缩放图片(平铺) - (UIImage *)resizeImage:(NSString *)imgName { UIImage *bgImage = [UIImage imageNamed:im ...
- css如何将图片横向平铺?
在CSS中,可以使用background(背景)属性来添加图片,默认图片是向x轴和y轴重复.那么css如何将图片横向平铺?下面本篇文章就来给大家介绍一下使用CSS将图片横向平铺的方法,希望对大家有所帮 ...
- CSS背景颜色、背景图片、平铺、定位、固定
CSS背景颜色设置 background-color:red;如设置背景颜色为红色: 背景颜色设置支持3种写法: 颜色名 16进制 rgb CSS背景图片颜色设置 background-image:u ...
- 如何通过CSS实现背景图片自动平铺或拉伸至整个屏幕(自适应大小)
默认情况下,通过HTML代码的BODY标签设置好背景图片<body background="x.jpg"> 后,图片会自动横向和纵向平铺.这就会产生一些美观上的问题. ...
- 使用一个小图片tile平铺到ImageView中或Activity背景
方法两种: 首先必须在res/drawable目录下包含一个background.jpg 方法1:在res/drawable中创建一个xml文件(background_repeat.xml) 内容为 ...
- [UWP]通过自定义XamlCompositionBrushBase实现图片平铺
1. 什么是XamlCompositionBrushBase 我早就想试试自定义XamlCompositionBrushBase,但一直没机会.上一篇文章介绍到使用Win2D的BorderEffect ...
- <<< html图片背景平铺
CSS背景图片平铺技巧 使用CSS来设置背景图片同传统的做法一样简单,但相对于传统控制方式,CSS提供了更多的可控选项,我们先来看看最基本的设置图片的方法.html代码: 代码如下: <divi ...
- 一款js控制背景图片平铺
背景图片的平铺方法有很多种,纯色背景,渐变背景,图片背景,今天讲的是移动端的图片背景~~~~ <style> html,body{;;} .body{background: url(ima ...
随机推荐
- 支撑微博亿级社交平台,小白也能玩转Redis集群(原理篇)
Redis作为一款性能优异的内存数据库,支撑着微博亿级社交平台,也成为很多互联网公司的标配.这里将以Redis Cluster集群为核心,基于最新的Redis5版本,从原理再到实战,玩转Redis集群 ...
- Mac下载魔兽世界怀旧服客户端 for Mac
<魔兽世界>怀旧服2019年8月9日凌晨2点开启全球压力测试,并将于8月27日正式开服.<魔兽世界>十五年,青春有它否?不见的战友,难抹的回忆,说不出口的遗憾?来,让我们一起回 ...
- Jsoup-解析HTML工具(简单爬虫工具)
Jsoup-解析HTML工具(简单爬虫工具) 一.简介 jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS ...
- Java的事件自定义事件学习
课程设计要做一个游戏,由于对C++不是很熟悉,老师也准许使用java 或者其他的语言,在.net我学过事件,一种委托回调,但是在java 我不是很了解,应该原理都相同吧! 游戏大致是这样的,现在这在写 ...
- #10056. 「一本通 2.3 练习 5」The XOR-longest Path
题目描述 有一棵带权树,求这些边组成的路径的最大异或和. Solution 考场 SPFA 神奇 70 分代码 #include<cstdio> #include<cstdlib&g ...
- 学习 Antd Pro 前后端分离
1.前言 最近学习reactjs ,前些年用RN开发过移动端,入门还算轻松.现在打算使用 Antd Pro 实现前后端分离.要使用Antd Pro这个脚手架,必须熟悉 umi.dva.redux-sa ...
- 第三方软件 vnc提权
通过读取注册表十进制数 将得出的十进制数去掉第一个数其他转换成16进制 破解16进制数得到密码 vncx.exe -W 回车 输入16进制数 连接vnc 读取 vncx4.exe -w 8个数 自动破 ...
- spring security原理-学习笔记1-整体概览
整体概述 运行时环境 Spring Security 3.0需要Java 5.0 Runtime Environment或更高版本. 核心组件 SecurityContextHolder,Securi ...
- 《HelloGitHub》第 43 期
兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...
- JVM 启动调优总结
启动命令 格式: java -jar 命令行参数 jar包路径 .示例如下 java -Dfile.encoding=utf-8 -jar -XX:MetaspaceSize=128m -XX:Max ...