Используя 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
метод.