我正在尝试为WPF绘图程序实现泛洪填充工具。我试图通过确保每个绘图操作首先写入位图来绕过任何矢量方法。然后将位图设置为画布。
将图像传递到画布时出现问题。它不使用相对位置设置图像。图像将比我更好地解释。
填充之前:
填写后:
图像位图相对于窗口写入并与工具栏重叠。我想知道如何防止这种情况发生。附件是我的Fill类的相关代码。
public override void OnMouseDown(CCDrawingCanvas canvas, System.Windows.Input.MouseButtonEventArgs e) {
double dpi = 96d;
// Get the size of the canvas
System.Windows.Size size = new System.Windows.Size((int)canvas.ActualWidth, (int)canvas.ActualHeight);
// Measure and arrange the surface
canvas.Measure(size);
canvas.Arrange(new Rect(size));
RenderTargetBitmap source = new RenderTargetBitmap(
(int)canvas.ActualWidth,
(int)canvas.ActualHeight,
dpi,
dpi,
PixelFormats.Pbgra32);
source.Render(canvas);
WriteableBitmap modifiedImage = new WriteableBitmap(source);
int h = modifiedImage.PixelHeight;
int w = modifiedImage.PixelWidth;
int[] pixelData = new int[h * w];
int widthInByte = modifiedImage.PixelWidth * (modifiedImage.Format.BitsPerPixel / 8);
modifiedImage.CopyPixels(pixelData, widthInByte, 0);
int oldColor = BitConverter.ToInt32(new byte[] { System.Drawing.Color.White.B, System.Drawing.Color.White.G, System.Drawing.Color.White.R, System.Drawing.Color.White.A }, 0);
int newColor = BitConverter.ToInt32(new byte[] { System.Drawing.Color.Black.B, System.Drawing.Color.Black.G, System.Drawing.Color.Black.R, System.Drawing.Color.Black.A }, 0);
// Perform the recursive fill
FloodFill(pixelData, (int)p.X, (int)p.Y, w, h, oldColor, newColor);
modifiedImage.WritePixels(new Int32Rect(0, 0, w, h), pixelData, widthInByte, 0);
newFill = new GraphicsFill(modifiedImage);
// Adds newFill to canvas.GraphicsList
AddObject(canvas, newFill);
}
XAML代码:
<Window x:Class="ccGui.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:effects="clr-namespace:System.Windows.Media.Effects;assembly=presentationcore"
xmlns:lib="clr-namespace:ccDrawingLib;assembly=ccDrawingLib"
xmlns:local="clr-namespace:ccGui"
Title="MainWindow" Height="600" Width="800">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="New" Command="ApplicationCommands.New" />
<MenuItem Header="Open" Command="ApplicationCommands.Open" />
<MenuItem Header="Save" Command="ApplicationCommands.Save" />
<MenuItem Header="Save As" Command="ApplicationCommands.SaveAs" />
<MenuItem Header="Close" Command="ApplicationCommands.Close" />
</MenuItem>
<MenuItem Header="Tool" Name="menuTools">
<MenuItem Header="Brush" Name="ccToolBrush" Tag="Brush" />
<MenuItem Header="Fill" Name="ccToolFill" Tag="Fill" />
</MenuItem>
</Menu>
<lib:CCDrawingCanvas x:Name="canvas" Background="White" />
</DockPanel>
</Window>
答案 0 :(得分:1)
在WPF中,几乎所有UI控件都扩展了Visual
类。您可以使用Visual
引用传递给RenderTargetBitmap.Render
Method,以便轻松保存该UI控件的图像。在我看来,您不需要在Shape
和BitMapImage
之间切换以填充Shape
。我猜你在绘制形状时使用的是Path
。如果这是真的,那么您可以使用Path.Fill
属性来填充它,而无需进行任何手动计算。
此外,如果您在每个新绘制的形状上设置Panel.Zindex
Attached Property并且每次使用下一个更高的Zindex
值,那么最新的形状将始终位于较低的形状之上,就像在绘图标准程序。您甚至可以让用户使用此属性切换其绘制图片的形状图层。