[UWP]通过自定义XamlCompositionBrushBase实现图片平铺
1. 什么是XamlCompositionBrushBase
我早就想试试自定义XamlCompositionBrushBase,但一直没机会。上一篇文章介绍到使用Win2D的BorderEffect实现图片的平铺功能,原理很简单,但每次都要写这些代码很繁琐,正好就用这个作为例子试试XamlCompositionBrushBase。
CompositionBrush灵活多变,它的基本用法如下:
- 通过Compositor创建CompositionBrush;
- 配置CompositionBrush;
- 创建SpriteVisual并将它的Brush设置为CompositionBrush;
- 使用ElementCompositionPreview.SetElementChildVisual 将SpriteVisual设置到某个UIElement的可视化层里。
这些步骤很繁琐,而且不能用在XAML中。XamlCompositionBrushBase提供了将CompositionBrush用在XAML中一个桥梁,他继承自Brush
类,可以直接像普通的XAML 画笔(如SolidColorBrush)那样直接用在XAML中。
如上图所示,Windows Community Toolkit中已经提了很不少XamlCompositionBrushBase的实现,它们的使用方式已经有很多文章介绍,这里不一一列举。
2. 自定义XamlCompositionBrushBase
这篇文章将介绍一个自定义的画笔:TiledImageBrush
,它的主要目标是实现ImageBrush没有的图片平铺功能,并且它可以在XAML中使用,使用方式如下:
<Rectangle IsHitTestVisible="False">
<Rectangle.Fill>
<controls:TiledImageBrush Source="ms-appx:///Assets/flutter.png"/>
</Rectangle.Fill>
</Rectangle>
顺便复习下普通的ImageBrush的用法:
<Rectangle >
<Rectangle.Fill>
<ImageBrush ImageSource="ms-appx:///Assets/flutter.png"/>
</Rectangle.Fill>
</Rectangle>
看起来TiledImageBrush的用法是不是和ImageBrush很像?接下来讲解TiledImageBrush
的实现步骤。TiledImageBrush
继承自XamlCompositionBrushBase
,而实现XamlCompositionBrushBase
的一般步骤如下:
protected override void OnConnected()
{
// Delay creating composition resources until they're required.
if (CompositionBrush == null)
{
CompositionBrush = CreateCompositionBrush();//Create A CompositionBrush.
}
}
protected override void OnDisconnected()
{
// Dispose of composition resources when no longer in use.
if (CompositionBrush != null)
{
CompositionBrush.Dispose();
CompositionBrush = null;
}
}
首先重写OnConnected,当画笔在屏幕上首次用于绘制元素时会调用这个函数。在这个函数里创建CompositionBrush并赋值给XamlCompositionBrushBase.CompositionBrush。
然后重写OnDisconnected,它在画笔不再用于绘制任何元素时被调用。在这个函数里尽可能地释放各种资源,例如CompositionBrush
。这两步就是实现XamlCompositionBrushBase
的基本步骤。
创建CompositionBrush有很多种玩法,我之前写过两篇文章分别介绍 CompositionBrush入门及 在CompositionBrush上使用Effect。这里使用使用Win2D的BorderEffect实现图片的平铺功能这篇文章里介绍到的代码,首先使用LoadedImageSurface.StartLoadFromUri
创建CompositionSurfaceBrush
,然后加入到BorderEffect里实现图片平铺,然后把产生的CompositionEffectBrush赋值给XamlCompositionBrushBase.CompositionBrush
。
TiledImageBrush中添加了Source
属性用于设置图片Uri(实际上是个ImageSource类型),模仿ImageBrush,这里的Source也是一个ImageSource类型的属性,虽然实际上使用的是它的UriSource。详细代码如下:
public ImageSource Source
{
get => (ImageSource)GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
private void UpdateSurface()
{
if (Source != null && _surfaceBrush != null)
{
var uri = (Source as BitmapImage)?.UriSource ?? new Uri("ms-appx:///");
_surface = LoadedImageSurface.StartLoadFromUri(uri);
_surfaceBrush.Surface = _surface;
}
}
OnConnected
的详细代码如下:
protected override void OnConnected()
{
base.OnConnected();
if (CompositionBrush == null)
{
_surfaceBrush = Compositor.CreateSurfaceBrush();
_surfaceBrush.Stretch = CompositionStretch.None;
UpdateSurface();
_borderEffect = new BorderEffect()
{
Source = new CompositionEffectSourceParameter("source"),
ExtendX = Microsoft.Graphics.Canvas.CanvasEdgeBehavior.Wrap,
ExtendY = Microsoft.Graphics.Canvas.CanvasEdgeBehavior.Wrap
};
_borderEffectFactory = Compositor.CreateEffectFactory(_borderEffect);
_borderEffectBrush = _borderEffectFactory.CreateBrush();
_borderEffectBrush.SetSourceParameter("source", _surfaceBrush);
CompositionBrush = _borderEffectBrush;
}
}
这样一个基本的XamlCompositionBrush就完成了,完整的代码可以在这里查看:
OnePomodoro_TiledImageBrush.cs at master
3. 参考
XamlCompositionBrushBase Class (Windows.UI.Xaml.Media) - Windows UWP applications _ Microsoft Docs
WindowsCommunityToolkit_Microsoft.Toolkit.Uwp.UI.Media_Brushes at master
Working with Brushes and Content – XAML and Visual Layer Interop, Part One - Windows Developer Blog
[UWP]通过自定义XamlCompositionBrushBase实现图片平铺的更多相关文章
- ie8下背景图片平铺问题
IE9+及其他浏览器实现背景图片平铺可能需要一个属性就可以background-size:100%/cover; 但是ie8下background-size是不兼容的,因此我们需要用到滤镜,来解决背景 ...
- Duilib技巧:背景图片平铺
贴图的描述 方式有两种 // 1.aaa.jpg // 2.file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0 ...
- android实现图片平铺效果&WebView多点触控实现缩放
1.图片平铺效果实现非常简单,只要在xml中添加一个 android:tileMode的属性就可以了.首先在drawable文件夹中添加自己的my.xml文件.代码: Java代码 <?xml ...
- Canvas 图片平铺设置
/** * 图片平铺 */ function initDemo7(){ var canvas = document.getElementById("demo7"); if (!ca ...
- iOS UIButton 设置图片平铺
UIImage *image2 = [UIImage imageNamed:imgName]; CGFloat top = ; // 顶端盖高度 CGFloat bottom = ; // 底端盖高度 ...
- Android中设定背景图片平铺。
注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在做Android开发时,我们常常需要为程序设定一个背景,但由于现在的Android设备尺寸不一,如果随便设置一个图片为背景,那么很 ...
- 一款js控制背景图片平铺
背景图片的平铺方法有很多种,纯色背景,渐变背景,图片背景,今天讲的是移动端的图片背景~~~~ <style> html,body{;;} .body{background: url(ima ...
- [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]
场景: 1.当你须要截取图片部分区域作为某个控件的背景. 2.须要平铺图片到一个大区域让他自己主动放大时. 3.或者须要合并图片时. 代码: CDC sdc; CDC ddc; sdc.CreateC ...
- LODOP中设置设置图片平铺水印,超文本透明
之前的博文:LODOP中平铺图片 文本项Repeat. 该博文中是平铺的图片,上面是文本.如果是图片add_print_image和add_print_text纯文本,这两个打印项设计的,可以直接通过 ...
随机推荐
- RequireJS 插件
网址:http://www.requirejs.cn/docs/api.html#i18n RequireJS的插件: Text:自动加载一些非js的文本文件. domReady:确保在Dom Rea ...
- Ubuntu 安装mysql & 自定义数据存储目录
一.安装 apt-get install mysql-server 执行过程如下: root@duke:~# apt-get install mysql-server 正在读取软件包列表... 完成 ...
- c++11::std::is_same/decay
#include <type_traits> std::is_same 判断类型是否一致 通过std::is_same即可判断两个类型是否一样,特别在模板里面,在不清楚模板的参数时,此功能 ...
- go-结构体和方法
结构体类型的字面量由关键字type.类型名称.关键字struct,以及由花括号包裹的若干字段声明组成. type Person struct { Name string Gender string A ...
- vue——父子组件间传值
(1)父组件给子组件传值(商品详情页): 根据订单类型,判断显示立即购买/立即拼单: 通过props来传递参数 父组件(商品详情页) 父组件调用子组件,在子组件的标签中,通过:数据名称=”数据”的形式 ...
- 自然语言处理(NLP)
苹果语音助手Siri的工作流程: 听 懂 思考 组织语言 回答 这其中每一步骤涉及的流程为: 语音识别 自然语言处理 - 语义分析 逻辑分析 - 结合业务场景与上下文 自然语言处理 - 分析结果生成自 ...
- Mysql高手系列 - 第26篇:聊聊如何使用mysql实现分布式锁
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第26篇. 本篇我们使用my ...
- 微信小程序如何发送订阅消息,正确姿势来了,建议收藏!
小程序订阅消息公测已经有些日子,今天以世界上最好的语言(PHP)为例,说一下如何发送订阅消息. 1.订阅消息 其实如果用过模板消息的话,改用订阅消息挺简单的,看一下官方文档稍加摸索就能使用. 但是对于 ...
- ES6基本语法入门
一.用let代替var声明变量 ES5中,我们可以在代码中任意位置声明变量,甚至可以重写已经声明的变量,ES6引入了一个let关键字,它是新的var. let language = 'javascri ...
- abp(net core)+easyui+efcore实现仓储管理系统——EasyUI之货物管理六(二十四)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...