绘图上下文中的WPF清除区域?

时间:2014-10-25 04:42:28

标签: wpf drawingcontext

所以我使用DrawingContext和DrawingVisual制作透明的PNG。

在DrawingContext中,我画了一个矩形。

我现在想要“切出”矩形内的一个圆圈。我该怎么做呢?我没有在绘图上下文中找到任何清除区域的函数。

1 个答案:

答案 0 :(得分:4)

您可以尝试使用 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中,然后您可以通过多种方式显示此位图。

以下是截图:

enter image description here

黑色区域表示颜色是透明的。

如果您想剪切一些复杂的图像(例如绘制的文本或图像)。您可以将CombinedGeometry变为某种OpacityMaskBrush类型)。我们可以把它变成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());
}

enter image description here

请注意,rect应该具有整个绘图的大小。然后定位 hole 和其他绘制的东西就像你想要的一样。

最后,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;