一种实现此功能的方法是使用Composition效果系统。
先决条件:
1.至少针对10586版本进行目标定位(在此之前,Composition API是实验性的)。
2.虽然不是必需的,但具备基本的视觉层理解会更好。我写了一篇博客文章作为该主题的介绍
here。
3.添加Win2D nuget包。
另外,您可以查看我写的一个gist
here,这是一种在XAML应用程序中使用Composition API快速启动的方法。它还演示了使用效果。不仅如此,它还涵盖了使用Composition API加载图像(使用我编写的软件包)。
入门指南:
你需要做的与代码片段非常相似,但不是定义一个
InvertEffect
,而是同时定义一个
CompositeEffect
和一个
ColorSourceEffect
。这将使用图像作为“掩码”,并将图像中的白色替换为一种颜色。你可以像这样定义效果:
IGraphicsEffect graphicsEffect = new CompositeEffect
{
Mode = Microsoft.Graphics.Canvas.CanvasComposite.DestinationIn,
Sources =
{
new ColorSourceEffect
{
Name = "colorSource",
Color = Color.FromArgb(255, 255, 255, 255)
},
new CompositionEffectSourceParameter("mask")
}
};
下一步是创建一个效果工厂:
var effectFactory = compositor.CreateEffectFactory(graphicsEffect, new string[] { "colorSource.Color" });
第二个参数虽然不是必需的,但在这种情况下可能是您想要的。设置此参数允许您在编译效果后更改属性,从而使您可以手动设置它并创建每个新的效果画笔或对效果画笔上的属性进行动画处理。我们只需手动设置它。使用您的新效果工厂创建一个新的效果画笔。请注意,此工厂可以使用上面使用的定义创建许多新的效果画笔:
var effectBrush = effectFactory.CreateBrush()
但是,首先您需要将图像应用为蒙版。您可以使用我编写的名为 CompositionImageLoader 的库将图像加载到表面上。您也可以在 nuget 上下载它。创建带有图像的表面后,创建一个 CompositionSurfaceBrush
并将其应用于效果。
var imageLoader = ImageLoaderFactory.CreateImageLoader(compositor);
var surface = imageLoader.LoadImageFromUri(new Uri("ms-appx:///Assets/Images/HAvng.png"));
var brush = compositor.CreateSurfaceBrush(surface);
effectBrush.SetSourceParameter("mask", brush);
请注意,您应该将ImageLoader保存在某个地方,因为反复创建它将会很昂贵。剩下的事情就是将效果笔刷应用于可视对象并设置颜色:
visual.Brush = effectBrush
effectBrush.Properties.InsertColor("colorSource.Color", Colors.Red)
然后你就完成了!请注意,如果您想在此之后更改颜色,只需使用新的颜色调用与上述相同的InsertColor
方法即可。
最终产品
在我的测试代码中,该方法如下:
var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
var visual = compositor.CreateSpriteVisual();
visual.Size = new Vector2(83, 86);
visual.Offset = new Vector3(50, 50, 0);
_imageLoader = ImageLoaderFactory.CreateImageLoader(compositor);
var surface = _imageLoader.LoadImageFromUri(new Uri("ms-appx:///Assets/Images/HAvng.png"));
var brush = compositor.CreateSurfaceBrush(surface);
IGraphicsEffect graphicsEffect = new CompositeEffect
{
Mode = Microsoft.Graphics.Canvas.CanvasComposite.DestinationIn,
Sources =
{
new ColorSourceEffect
{
Name = "colorSource",
Color = Color.FromArgb(255, 255, 255, 255)
},
new CompositionEffectSourceParameter("mask")
}
};
_effectFactory = compositor.CreateEffectFactory(graphicsEffect, new string[] { "colorSource.Color" });
var effectBrush = _effectFactory.CreateBrush();
effectBrush.SetSourceParameter("mask", brush);
visual.Brush = effectBrush;
effectBrush.Properties.InsertColor("colorSource.Color", Colors.Red);
ElementCompositionPreview.SetElementChildVisual(this, visual);
请注意,在此示例中,可视化对象附加到了
this
,也就是我的MainPage页面上。你可以将其附加到任何XAML元素上。如果你想看一个自定义控件的示例,它可以在你调整控件大小时创建并调整大小你的可视化对象,你可以在
这里找到它。
如果你想了解更多有关Composition相关的信息,请访问我们的
GitHub页面!我们将很乐意帮助你解决关于该API的任何问题。