2014-02-10 68 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值,那麼最新的形狀將總是位於較低的形狀之上,就像在繪圖標準程序中一樣。你甚至可以讓用戶使用這個屬性來切換他們繪製的圖片的形狀圖層。