[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中的图片平铺功能现在就差创建一个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
,效果如下:


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
,效果如下: