首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得四舍五入的图像源或位图图像,以便在UWP中裁剪椭圆形状的图像

问如何获得四舍五入的图像源或位图图像,以便在UWP中裁剪椭圆形状的图像
EN

Stack Overflow用户
提问于 2020-10-30 11:54:33
回答 1查看 48关注 0票数 1

我需要裁剪的椭圆形状的图像,但我不想使用椭圆和填充ImageBrush在这个link中提到,而是我需要的位图本身是四舍五入/椭圆而不是矩形。

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

有没有其他的解决方案?这也将是更好,如果我可以剪裁的图像在椭圆格式。

但是图像中的剪辑只接受RectangleGeometry。

EN

回答 1

Stack Overflow用户

发布于 2020-10-30 13:21:32

您可以创建一个自定义UserControl,并在其中使用win2d CanvasControl显示图像,您可以在其中绘制您想要的任何形状的图像,使用"CreateLayer“函数来遮罩绘制的图像与形状。例如

在xaml:

代码语言:javascript
复制
<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>

在代码背后:

代码语言:javascript
复制
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), typeof(MyImageControl), 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, 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,请原谅任何错误,因为我是在路上写的,还没有测试过它。这只是一个想法

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64602515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档