所以我正在使用 DrawingContext 和 DrawingVisual 生成一个透明的 PNG。
在 DrawingContext 中,我画了一个矩形。
我现在想在矩形内“切出”一个圆圈。我该怎么做呢?我在绘图上下文中没有找到任何功能来清除区域。
所以我正在使用 DrawingContext 和 DrawingVisual 生成一个透明的 PNG。
在 DrawingContext 中,我画了一个矩形。
我现在想在矩形内“切出”一个圆圈。我该怎么做呢?我在绘图上下文中没有找到任何功能来清除区域。
您可以尝试使用CombinedGeometry组合 2 个几何图形(每次)。它GeometryCombineMode
允许您指定一些逻辑组合。在这种情况下,您需要的是GeometryCombineMode.Xor
. 矩形和椭圆(圆)的交点将被剪掉。这是演示它的简单代码:
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
. 您可以使用 someRenderTargetBitmap
将其捕获到某种 BitmapSource 中,然后您有很多方法可以显示此位图。
这是屏幕截图:
黑色区域表示颜色是透明的。
万一你想剪出一些复杂的图像(如绘制的文本或图像)。你可以把它CombinedGeometry
变成某种OpacityMask
(类型的Brush
)。我们可以把它变成a 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
which is a 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;