繁体   English   中英

UWP透明png颜色叠加

[英]UWP Transparent png color overlay

我的 UWP c# 项目中有一个图像,它是一个带有白色前景的透明 png。 我现在想将此 png 图像中的白色更改为另一种颜色(如蓝色)。

示例(请注意,彩色图像没有透明背景。这是由于我使用的图像处理软件不好,并演示了白色的变化。背景在最终结果中应该是透明的)。

泡泡1 泡泡2

我记得,这在统一中是可能的,现在我想在 uwp-app 中做到这一点。 我想过使用Lumia ImagingSDKComposition API ,但不知道,用任何一个来做都很热。

一种方法是使用合成效果系统。

先决条件

  1. 至少针对 build 10586(Composition API 在此之前是实验性的)。
  2. 虽然不是严格要求,但对视觉层有基本的了解也无妨。 我写了一篇博客文章是介绍这个主题在这里
  3. 添加 Win2D nuget 包。

此外,您可以查看我在此处编写的要点,这是一种在 XAML 应用程序中使用 Composition API 启动和运行的快速方法。 它也演示了使用效果。 不仅如此,它还涵盖了使用 Composition API 加载图像(使用我编写的包)。

入门

您需要做一些与要点非常相似的事情,但不是定义InvertEffect ,而是需要同时定义CompositeEffectColorSourceEffect 这将做的是拍摄图像并将其用作“蒙版”,然后用颜色替换图像中的白色。 您可以这样定义效果:

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 标记中定义的自定义控件示例,该标记会在您调整控件大小时创建并调整视觉对象的大小,您可以在此处找到。

要查看更多与 Composition 相关的内容,请访问我们的GitHub 页面 我们很乐意帮助您解决有关 API 的任何问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM