UWP透明png颜色叠加

时间:2016-03-21 16:26:13

标签: c# win-universal-app imaging

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

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

bubble1 bubble2

我记得,这在团结中是可能的,现在我想在uwp-app中做到这一点。我考虑过使用Lumia ImagingSDKComposition API,但不知道,对这两种方法都很热。

1 个答案:

答案 0 :(得分:4)

您可以使用合成效果系统。

<强>先决条件

  1. 至少定位构建10586(之前的Composition API是实验性的)。
  2. 虽然不是严格要求,但对视觉层有基本的了解不会受到伤害。我写了一篇博客文章,介绍了这个主题here
  3. 添加Win2D nuget包。
  4. 此外,您可以查看我写的here的要点,这是在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,这是我的主页。您可以将它附加到任何XAML元素。如果您想查看自定义控件的示例,您可以在XAML标记中定义该控件,以便在调整控件大小时创建并调整视觉大小,您可以找到here

    要查看更多与作文相关的内容,请转到我们的GitHub page!如果您对API有任何疑问,我们将非常乐意为您提供帮助。