【问题标题】:Using Win2D, how to crop an image to a circle使用 Win2D,如何将图像裁剪为圆形
【发布时间】:2018-05-24 00:51:22
【问题描述】:

看起来这应该很简单,但我真的很难找到任何关于如何做到这一点的文档。我只是想裁剪图像以将正方形变成圆形。

有很多关于它的讨论,但我似乎找不到一个很好的例子来说明如何使用 UWP/Win2D 做到这一点。

这里有一些代码来说明我试图在我的 cmets 中描述的问题:

// draw a 10x10 grid of circles
var bitmap = await CanvasBitmap.LoadAsync(sender, "Assets/ice.png"); // hex-shaped image is 250x220 pixels 
var brush = new CanvasImageBrush(sender, bitmap);
for (var i = 0; i < 10; i++)
{
    for (var j = 0; j < 10; j++)
    {
        //_drawingSession.FillCircle(new Vector2(i * 50, j * 50), (float)(25), Colors.Blue);
        _drawingSession.FillCircle(new Vector2(i * 50, j * 50), (float)(25), brush);
    }
}

下图显示了如何根据要绘制目标圆的矢量从相同的 x/y 坐标切割画笔。

注意:FillEllipse() 也会产生同样的效果。

【问题讨论】:

    标签: c# uwp win2d


    【解决方案1】:

    你可以尝试使用CanvasImageBrushCanvasDrawingSession.FillEllipse Method来实现。

    private async void canvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, 
        Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
    {
        using (CanvasBitmap bitmap = await CanvasBitmap.LoadAsync(sender, "Assets/image.jpg"))
        {
            CanvasImageBrush canvasImageBrush = new CanvasImageBrush(sender, bitmap);
            args.DrawingSession.FillEllipse(new System.Numerics.Vector2(100f), 100, 100, canvasImageBrush);
        }
    }
    

    ------------ 更新 -------------

    如果要从图片源中剪出一个圆形,可以配置CanvasImageBrush.Transform属性对图片进行缩放,然后剪下圆形并显示在画布上。

    private async void canvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, 
        Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
    {
        using (CanvasBitmap bitmap = await CanvasBitmap.LoadAsync(sender, "Assets/image.jpg"))
        {
            CanvasImageBrush canvasImageBrush = new CanvasImageBrush(sender, bitmap);
            System.Numerics.Vector2 center = new System.Numerics.Vector2((float)(bitmap.Size.Width / 2),
                (float)(bitmap.Size.Height / 2));
            canvasImageBrush.Transform = System.Numerics.Matrix3x2.CreateScale(0.5F, center);
            args.DrawingSession.FillEllipse(center, 160, 160, canvasImageBrush);
        }
    }
    

    您应该更改我上面代码中的一些参数以满足您的要求,例如Matrix3x2.CreateScale 方法中的比例。

    【讨论】:

    • 这似乎有点工作,但看起来中心点(可能还有半径值)也被用作用于画笔的图像中的偏移量。
    • 当我将画笔切换为纯色时,我成功绘制了一个圆圈网格。但是,当使用画笔时,只有一个圆圈被正确绘制。其余的要么看起来像涂片,要么根本没有绘制任何图像。
    • 经过进一步调查,在我看来,列表中的第一个参数被用作椭圆绘制位置的目标坐标,以及位图的偏移量被用作刷子。这似乎就是为什么超出边界 220x250(这是我的位图大小)的所有内容都被绘制为模糊条纹的原因。我不确定这是否是 Win2D 中的一个错误,或者这是一个预期的“功能”。
    • 那么您能否提供更多代码让我看到您的问题以及您想要的详细效果?
    • 我已经更新了原始帖子以显示我上面描述的问题。就我而言,我不想制作一个圆圈网格,但我需要使用图像作为源,从中剪出一个圆圈,然后在画布上重新绘制该圆圈。 10x10 网格显示我无法使用 FillCircle 和位图画笔做我想做的事情。
    【解决方案2】:

    好的,在与 GitHub Win2D 项目的一位研究员交谈后,我终于对它的工作原理有了一个明确的答案——它的工作方式与我预期的完全不同。

    首先,位图画笔图像默认位于画布上的 0,0。

    就我而言,我想从图像中剪下一个圆圈,然后在画布上的其他地方绘制它。这需要 2 个独立的数学位。

    首先,您需要将位图的左上角 (TLC) 定位到要绘制圆的位置。这是通过设置画笔的 Transform 属性来完成的。在我的示例中,我将图像 TLC 设置为 300/300;

    // create the brush
    var brush = new CanvasImageBrush(sender, _tiles[1]);
    brush.Transform = Matrix3x2.CreateTranslation(300, 300);
    

    现在,要使用画笔图像剪切/绘制圆圈,我必须描述图像中心在画布上的位置。我的图像是 250x220。

    // 300+250/2, 300+220/2 = 425, 410
    _args.DrawingSession.FillCircle(new Vector2(425, 410), (float)(110), brush);
    

    这产生了从我的原始位图中切出一个圆圈并将其绘制在画布上所需位置的效果。

    希望这已经足够清楚了。我知道我确实很难找到答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-01
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 2012-10-08
      • 2021-04-23
      • 1970-01-01
      相关资源
      最近更新 更多