我想在 WPF 中绘制一个矩形(通过代码)并填充它的外部。
这是一个例子:
矩形的外部是灰色的(不透明度低),矩形的填充是透明的。
您还可以使用半透明Path
元素覆盖您的图像,该元素使用 aCombinedGeometry
将一个非常大的外部矩形与一个内部矩形相结合:
<Grid>
<Image Name="image" Source="C:\Users\Public\Pictures\Sample Pictures\Koala.jpg"/>
<Path Fill="#AAFFFFFF">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Xor">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,10000,10000"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry x:Name="transparentRect" Rect="150,100,200,100"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
</Grid>
您现在可以根据需要以编程方式调整成员的Rect
属性transparentRect
。
您可以使用 OpacityMask 和 DrawingBrush 的组合:
XAML:
<Grid Background="Gray">
<Image Name="image"Source="...">
<Image.OpacityMask>
<DrawingBrush x:Name="mask"/>
</Image.OpacityMask>
</Image>
</Grid>
代码隐藏:
private void UpdateOpactiyMask()
{
Point topLeft = new Point();
Point bottomRight = new Point(image.ActualWidth, image.ActualHeight);
GeometryDrawing left = new GeometryDrawing();
left.Brush = borderBrush;
left.Geometry = new RectangleGeometry(new Rect(topLeft, new Point(SelectedArea.Left, bottomRight.Y)));
GeometryDrawing right = new GeometryDrawing();
right.Brush = borderBrush;
right.Geometry = new RectangleGeometry(new Rect(new Point(SelectedArea.Right, topLeft.Y), bottomRight));
GeometryDrawing top = new GeometryDrawing();
top.Brush = borderBrush;
top.Geometry = new RectangleGeometry(new Rect(new Point(SelectedArea.Left, topLeft.Y), new Point(SelectedArea.Right, SelectedArea.Top)));
GeometryDrawing bottom = new GeometryDrawing();
bottom.Brush = borderBrush;
bottom.Geometry = new RectangleGeometry(new Rect(new Point(SelectedArea.Left, SelectedArea.Bottom), new Point(SelectedArea.Right, bottomRight.Y)));
GeometryDrawing center = new GeometryDrawing();
center.Brush = selectionBrush;
center.Geometry = new RectangleGeometry(SelectedArea);
DrawingGroup drawing = new DrawingGroup();
drawing.Children.Add(left);
drawing.Children.Add(right);
drawing.Children.Add(top);
drawing.Children.Add(bottom);
drawing.Children.Add(center);
mask.Drawing = drawing;
}
SelectedArea 是一个矩形。
您可以使用UIElement.Clip
属性:
<Window x:Class="So17720970_RectangularBoublik.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
SizeToContent="WidthAndHeight">
<Grid Width="500" Height="500">
<Image Source="http://i.stack.imgur.com/Py65S.jpg"/> <!-- image -->
<Rectangle Fill="#AA000000"> <!-- selection -->
<Rectangle.Clip>
<GeometryGroup FillRule="Nonzero"> <!-- selection clip: -->
<RectangleGeometry Rect="0 0 500 200"/> <!-- top -->
<RectangleGeometry Rect="0 0 100 500"/> <!-- left -->
<RectangleGeometry Rect="0 300 500 200"/> <!-- bottom -->
<RectangleGeometry Rect="400 0 100 500"/> <!-- right -->
</GeometryGroup>
</Rectangle.Clip>
</Rectangle>
<Rectangle StrokeThickness="1" Stroke="Black" StrokeDashArray="1 2" SnapsToDevicePixels="True"
Margin="100 200 100 200"/> <!-- "ants" -->
</Grid>
</Window>
这是使用 OpacityMask 的解决方案的一种变体。它不是在代码中完成,而是在 XAML 中完成。此外,它颠倒了逻辑:它不是绘制 4 个边框矩形,而是在彼此的顶部绘制 2 个矩形。最后,这个解决方案的重要属性是中心透明矩形的大小是相对于图像大小的(而不是绝对像素)。您不需要知道实际图像大小或它是如何拉伸/定位的(对于 Stretch="Uniform" 尤其重要)。在这里,我将图像大小 (maskRect) 指定为 1,1,并使用小数作为相对掩码大小和位置 (transpRect)。您也可以将图像大小指定为 100,100 并使用掩码的百分比值(或者,甚至使用实际像素值)。
<Grid Background="#FFF4F4F5" >
<Image Name="PhotoImage" Source="...">
<Image.OpacityMask>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry x:Name="maskRect" Rect="0,0,1,1"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="#60000000" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry x:Name="transpRect" Rect=".25,.20,.40,.40"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<SolidColorBrush Color="Black" />
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Image.OpacityMask>
</Image>
</Grid>