Используя Win2D, как обрезать изображение в круг

Кажется, что это должно быть достаточно просто, но я действительно пытаюсь найти любую документацию о том, как я могу это сделать. Я просто хочу обрезать изображение, чтобы превратить квадрат в круг.

Существует много дискуссий по этому поводу, но я не могу найти хороший пример того, как сделать это с помощью UWP/Win2D.

Вот немного кода, чтобы проиллюстрировать проблему, которую я пытался описать в моих комментариях:

// 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().

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);

Теперь, чтобы вырезать / нарисовать круг, используя изображение кисти, я должен описать, где должен быть центр изображения на холсте. Мое изображение 250х220.

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

Это дает эффект вырезания круга из моего исходного растрового изображения и рисования его на холсте в нужном месте.

Надеюсь, это достаточно ясно. Я знаю, что, конечно, изо всех сил пытался найти ответ.

Вы можете попытаться использовать CanvasImageBrush и метод CanvasDrawingSession.FillEllipse для достижения этой цели.

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 метод.

Другие вопросы по тегам