2014-02-10 64 views
0

我正在尝试实施一个WPF绘图程序的洪水填充工具。我试图通过确保每个绘图动作首先写入位图来绕过任何矢量方法。位图然后设置为画布。添加一个图像

将图像传递到画布时出现问题。它不使用相对位置设置图像。这些图像会比我能解释得更好。

填充之前:

Before Fill

填充后:

enter image description here

图像的位图相对于写入窗口重叠的工具栏。我想知道如何防止这种情况发生。附件是我的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> 
+1

症状几乎看起来像是将新对象添加到父级或根级Visual而不是子级。一般来说,布局系统通常会阻止非相对布局,除非您真的尝试或将您添加到错误的父Visual /容器中。你能分享相关的XAML吗? –

+1

为什么人们会手动完成所有这些工作,只需使用形状类并使用['RenderTargetBitmap.Render'](http://msdn.microsoft.com/zh-cn/library/system .windows.media.imaging.rendertargetbitmap.render.aspx)方法? – Sheridan

+0

@JTrana我会尽快发布。 – Alex

回答

1

在WPF中,几乎所有的UI控件扩展Visual类。您可以使用该Visual引用传递给RenderTargetBitmap.Render Method以轻松保存该UI控件的图像。在我看来,你不应该继续在ShapeBitMapImage之间切换以填充你的Shape。我想你在绘制图形时使用了Path。如果这是真的,那么您可以使用Path.Fill属性来填充它,而无需执行任何手动计算。另外,如果您在每个新的绘制形状上设置Panel.Zindex Attached Property,并且每次都使用下一个较高的Zindex值,那么最新的形状将总是位于较低的形状之上,就像在绘图标准程序中一样。你甚至可以让用户使用这个属性来切换他们绘制的图片的形状图层。