如何在UWP中获取圆形图像源或位图图像以裁剪椭圆形图像

问题描述

我需要将图像裁剪为椭圆形,但我不想使用link中提到的Ellipse并用ImageBrush填充,相反,我需要将位图本身设置为圆形/椭圆形而不是矩形

有时候我想裁剪成矩形,有时是椭圆形,所以我不能使用椭圆和填充。

是否有其他解决方案?如果我可以以椭圆格式裁剪图像,那就更好了。

但是“图像中的剪辑”仅接受RectangleGeometry。

解决方法

您可以创建一个自定义UserControl,然后使用win2d CanvasControl显示图像,您可以在其中绘制所需形状的图像,并使用“ CreateLayer”功能遮盖图形形状。例如

在xaml:

<UserControl
    x:Class="UWPClassLib.MyImageControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UWPClassLib"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:win2d="using:Microsoft.Graphics.Canvas.UI.Xaml"
    mc:Ignorable="d">
    <win2d:CanvasControl x:Name="w2dCanvas"
                         Draw="w2dCanvas_Draw" />
</UserControl>

后面的代码:

public enum MaskShape
{
    rectangle,circle
}

public sealed partial class MyImageControl : UserControl
{
    public WriteableBitmap Bitmap
    {
        get { return (WriteableBitmap)GetValue(BitmapProperty); }
        set { SetValue(BitmapProperty,value); }
    }

    public static readonly DependencyProperty BitmapProperty = DependencyProperty.Register(nameof(Bitmap),typeof(WriteableBitmap),typeof(MyImageControl),new PropertyMetadata(null,OnBitmapPropertyChanged));

    private static void OnBitmapPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
    {
        var myctrl = (MyImageControl)d;
        myctrl.TryCreateResource();
    }

    public MaskShape Shape
    {
        get { return (MaskShape)GetValue(ShapeProperty); }
        set { SetValue(ShapeProperty,value); }
    }

    public static readonly DependencyProperty ShapeProperty = DependencyProperty.Register(nameof(Shape),typeof(MaskShape),new PropertyMetadata(MaskShape.circle));

    private CanvasBitmap Source;

    public MyImageControl()
    {
        this.InitializeComponent();
    }
    
    public void Invalidate()
    {
        w2dCanvas.Invalidate();
    }
    private void w2dCanvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
    {
        using (var session = args.DrawingSession)
        {
            session.Clear(Colors.Transparent);
            if (CheckResourceCreated())
            {
                using (var mask = GetMaskShape())
                using (var layer = session.CreateLayer(1.0f,mask))
                {
                    session.DrawImage(Source);
                }
                // either you can do that or can use
                // session.FillGeometry(mask,imagebrush); //and image brush can be made from source e.g.
                // imagebrush  = new CanvasImageBrush(w2dCanvas,Source);
            }
        }
    }

    private CanvasGeometry GetMaskShape()
    {
        switch (Shape)
        {
            default:
            case MaskShape.circle:
                var center = new System.Numerics.Vector2((float)this.ActualWidth / 2,(float)this.ActualHeight / 2);
                var radiusX = (float)this.ActualWidth / 2;
                var radiusY = (float)this.ActualHeight / 2;
                return CanvasGeometry.CreateEllipse(w2dCanvas,center,radiusX,radiusY);

            case MaskShape.rectangle:
                return CanvasGeometry.CreateRectangle(w2dCanvas,new Rect(0,this.ActualWidth,this.ActualHeight));
        }
    }

    private bool CheckResourceCreated()
    {
        if (Source == null)
        {
            TryCreateResource();
        }
        return (Source != null);
    }

    private void TryCreateResource()
    {
        try
        {
            if (Bitmap == null)
                return;

            Source = CanvasBitmap.CreateFromBytes(w2dCanvas,Bitmap.PixelBuffer.ToArray(),Bitmap.PixelWidth,Bitmap.PixelHeight,DirectXPixelFormat.B8G8R8A8UIntNormalized);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }
}

,现在您可以在任何以矩形或圆形显示图像的地方使用它。您只需要更改MaskShape并调用invalidate 请原谅任何错误,因为我在旅途中写了它,还没有测试它。 它只是一个想法