2014-10-25 2 views
3

Итак, я создаю прозрачный PNG, используя DrawingContext и DrawingVisual.WPF Clear Region в контексте рисования?

Внутри DrawingContext я нарисовал прямоугольник.

Теперь я хотел бы «вырезать» круг внутри прямоугольника. Как мне это сделать? Я не нашел никаких функций в рисовании контекста, чтобы очистить регион.

ответ

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 в какой-то 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()); 
} 

enter image description here

Обратите внимание, что 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; 
+0

Хорошо ... достаточно просто ... Тем не менее, у меня есть еще одно осложнение. Что, если вместо того, чтобы вырезать вытянутый круг из вытянутого прямоугольника, я хочу вырезать из нарисованного текста? –

+0

@JasonAxelrod см. Мое обновление. Единственное, что я мог придумать, это использовать некоторую «OpacityMask». –