UWP使用另一个图像作为遮罩遮罩图像

时间:2018-05-17 15:45:54

标签: c# xaml uwp mask uwp-xaml

有没有人知道在UWP中使用图像作为另一个图像的掩码的任何方法,我能看到的唯一屏蔽功能是CompositionMaskBrush,我不相信它可以达到我想要的效果。 我希望实现的一个例子如下。 我有一个坚固的黑色PNG形状的手机外壳,用户添加自己的图像,然后剪裁和掩盖到纯黑色PNG的尺寸 - 导致下面的图像。

任何帮助都将不胜感激。我花了很长时间浏览解决方案。

Example Image Here

1 个答案:

答案 0 :(得分:0)

只为其他需要和回答此问题的人发帖,但我终于找到了使用Win2D和Imageloader的解决方案。

这是ImageLoader的链接。请注意,我必须回滚几个版本才能使文档说明如何工作。以下链接指向我正在使用的版本。比此版本晚的任何内容都不适用于我要发布的示例代码。 https://www.nuget.org/packages/Robmikh.Util.CompositionImageLoader/0.4.0-alpha

    private Compositor _compositor;
    private IImageLoader _imageLoader;
    private CompositionEffectFactory _effectFactory;

    private async void InitMask()
    {


        // Store our Compositor and create our ImageLoader.
        _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
        _imageLoader = ImageLoaderFactory.CreateImageLoader(_compositor);

        // Setup our effect definition. First is the CompositeEffect that will take
        // our sources and produce the intersection of the images (because we selected
        // the DestinationIn mode for the effect). Next we take our CompositeEffect 
        // and make it the source of our next effect, the InvertEffect. This will take 
        // the intersection image and invert the colors. Finally we take that combined 
        // effect and put it through a HueRotationEffect, were we can adjust the colors
        // using the Angle property (which we will animate below). 
        IGraphicsEffect graphicsEffect = new HueRotationEffect
        {
            Name = "hueEffect",
            Angle = 0.0f,
            Source = new InvertEffect
            {
                Source = new CompositeEffect
                {
                    Mode = CanvasComposite.DestinationIn,
                    Sources =
                    {
                        new CompositionEffectSourceParameter("image"),
                        new CompositionEffectSourceParameter("mask")
                    }
                }
            }
        };
        // Create our effect factory using the effect definition and mark the Angle
        // property as adjustable/animatable.
        _effectFactory = _compositor.CreateEffectFactory(graphicsEffect, new string[] { "hueEffect.Angle" });

        // Create MangedSurfaces for both our base image and the mask we'll be using. 
        // The mask is a transparent image with a white circle in the middle. This is 
        // important since the CompositeEffect will use just the circle for the 
        // intersectionsince the rest is transparent.

        var managedImageSurface = await _imageLoader.CreateManagedSurfaceFromUriAsync(new Uri("http://sendus.pics/uploads/" + ImagePass + "/0.png", UriKind.Absolute));
        //var managedImageSurface = await _imageLoader.CreateManagedSurfaceFromUriAsync(new Uri("ms-appx:///Assets/colour.jpg", UriKind.Absolute));
        var managedMaskSurface = await _imageLoader.CreateManagedSurfaceFromUriAsync(new Uri("ms-appx:///" + MaskImage, UriKind.Absolute));

        // Create brushes from our surfaces.
        var imageBrush = _compositor.CreateSurfaceBrush(managedImageSurface.Surface);
        var maskBrush = _compositor.CreateSurfaceBrush(managedMaskSurface.Surface);

        // Create an setup our effect brush.Assign both the base image and mask image
        // brushes as source parameters in the effect (with the same names we used in
        // the effect definition). If we wanted, we could create many effect brushes
        // and use different images in all of them.
        var effectBrush = _effectFactory.CreateBrush();
        effectBrush.SetSourceParameter("image", imageBrush);
        effectBrush.SetSourceParameter("mask", maskBrush);

        // All that's left is to create a visual, assign the effect brush to the Brush
        // property, and attach it into the tree...
        var visual = _compositor.CreateSpriteVisual();

        visual.Size = new Vector2(MaskH, MaskW);
        visual.Offset = new Vector3(0, 300, 0);

        visual.Brush = effectBrush;

        ElementCompositionPreview.SetElementChildVisual(this, visual);
    }