一种方法是使用合成效果系统。
先决条件
- 至少以 build 10586 为目标(在此之前,Composition API 是实验性的)。
- 虽然没有严格要求,但对可视层有基本的了解不会有什么坏处。我写了一篇博文,介绍了这个话题here。
- 添加 Win2D nuget 包。
此外,您可以查看我写的 here 的要点,这是在 XAML 应用程序中使用组合 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 元素。如果您想查看可以在 XAML 标记中定义的自定义控件示例,该控件会在您调整控件大小时创建并调整您的视觉对象,您可以找到 here。
要查看更多与作曲相关的内容,请访问我们的GitHub page!如果您对 API 有任何疑问,我们很乐意为您提供帮助。