简体   繁体   中英

UWP Masking an image using another image as a mask

Does anybody know of any ways to use an image as a mask for another image in UWP, the only masking function I can see is CompositionMaskBrush which I don't believe can achieve what I want. An example of what I'm looking to achieve is the following. I have a solid black PNG in the shape of a mobile phone case, the user adds their own image which is then clipped and masked to the dimensions of the solid black PNG - Resulting in the image below.

Any help whatsoever would be greatly appreciated. I've spent quite a while browsing for a solution.

Example Image Here

Just posting for anybody else who needs and answer to this, but I finally managed to find a solution using Win2D and an Imageloader.

Here is a link to the ImageLoader. Note that I had to roll back a few versions in order make it work how the documentation states. The link below is to the version that I'm using. Anything later than this version will not work with the sample code I'm going to post. 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);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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