Вы можете использовать CombinedGeometry, чтобы объединить 2 геометрии (каждый раз). Он имеет GeometryCombineMode
, позволяющий указать некоторую логическую комбинацию. В этом случае вам нужно GeometryCombineMode.Xor
. Пересечение Rect и Ellipse (cirlce) будет вырезано. Вот простой код демонстрирует это:
DrawingVisual dv = new DrawingVisual();
using (var dc = dv.RenderOpen()) {
var rect = new Rect(0, 0, 300, 200);
var cb = new CombinedGeometry(GeometryCombineMode.Xor,
new RectangleGeometry(rect),
new EllipseGeometry(new Point(150, 100), 50, 50));
dc.DrawGeometry(Brushes.Blue, null, cb);
}
Я надеюсь, что вы знаете, как оказать DrawingVisual
. Вы можете использовать некоторый RenderTargetBitmap
, чтобы захватить его в какой-то BitmapSource, и тогда у вас есть много способов показать это растровое изображение.
Вот скриншот:
Черная область означает, что цвет является прозрачным.
Если вы хотите вырезать сложное изображение (например, нарисованный текст или изображение). Вы можете повернуть CombinedGeometry
в какой-то OpacityMask
(тип Brush
). Мы можем превратить его в DrawingBrush
и эта кисть может быть использована в качестве OpacityMask
, которые могут быть переданы в DrawingContext.PushOpacityMask
метод:
DrawingVisual dv = new DrawingVisual();
using (var dc = dv.RenderOpen()) {
var rect = new Rect(0, 0, 300, 200);
var cb = new CombinedGeometry(GeometryCombineMode.Xor,
new RectangleGeometry(rect),
new EllipseGeometry(new Point(150, 100), 50, 50));
var mask = new DrawingBrush(new GeometryDrawing(Brushes.Blue, null, cb));
dc.PushOpacityMask(mask);
dc.DrawImage(someImage, rect);
dc.DrawText(new FormattedText("Windows Presentation Foundation",
System.Globalization.CultureInfo.CurrentCulture,
System.Windows.FlowDirection.LeftToRight,
new Typeface("Lucida Bright"), 30, Brushes.Red){
MaxTextWidth = rect.Width,
MaxTextHeight = rect.Height,
TextAlignment = TextAlignment.Center
}, new Point());
}
Обратите внимание, что rect
должен иметь размер всего рисунка. Затем позиционирование отверстия и другие рисунки будут точными, как вы хотите.
Идентификационный номер DrawingVisual
также имеет полезное свойство под названием Clip
которое является Geometry
. Таким образом, вы можете подготовить CombinedGeometry
и присвоить его DrawingVisual.Clip
.
Предположим, у вас уже есть DrawingVisual
(с некоторыми рисунками, включая текст, изображения, ...). Следующий код будет удар отверстие через него:
//prepare the geometry, which can be considered as the puncher.
var rect = new Rect(0, 0, 300, 200);
var cb = new CombinedGeometry(GeometryCombineMode.Xor,
new RectangleGeometry(rect),
new EllipseGeometry(new Point(150, 100), 50, 50));
//punch the DrawingVisual
yourDrawingVisual.Clip = cb;
Хорошо ... достаточно просто ... Тем не менее, у меня есть еще одно осложнение. Что, если вместо того, чтобы вырезать вытянутый круг из вытянутого прямоугольника, я хочу вырезать из нарисованного текста? –
@JasonAxelrod см. Мое обновление. Единственное, что я мог придумать, это использовать некоторую «OpacityMask». –