2014-01-28 28 views
7

Also ich versuche, einen Snapshot meiner Leinwand in WPF C# zu machen, so dass ich es als PNG speichern kann. Das Bild wird derzeit nicht korrekt gespeichert, da es den linken und oberen Rand enthält.Speichern einer Leinwand in Png C# wpf

Das ist, was ich habe:

ein Rechteck für die Größe der Leinwand erstellen. Wenn canvas.Margin.Left und Top auf 0 gesetzt sind, hat das gespeicherte Bild die richtige Größe, aber der Offset tritt immer noch auf und schneidet somit den unteren und rechten Rand ab. gesetzt wird, um die Margin.Left und Top verursacht noch den Versatz auftreten, aber das gesamte Bild gespeichert ist, aber an der falschen Größe (margin.Left + Actual) anstatt nur Actual

Rect rect = new Rect(canvas.Margin.Left, canvas.Margin.Top, canvas.ActualWidth, canvas.ActualHeight); 

double dpi = 96d; 

RenderTargetBitmap rtb = new RenderTargetBitmap((int)rect.Right, (int)rect.Bottom, dpi, dpi, System.Windows.Media.PixelFormats.Default); 

rtb.Render(canvas); 

BitmapEncoder pngEncoder = new PngBitmapEncoder(); 
pngEncoder.Frames.Add(BitmapFrame.Create(rtb)); 

try 
{ 
    System.IO.MemoryStream ms = new System.IO.MemoryStream(); 

    pngEncoder.Save(ms); 
    ms.Close(); 

    System.IO.File.WriteAllBytes(filename, ms.ToArray()); 
} 
catch (Exception err) 
{ 
    MessageBox.Show(err.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
} 
+0

Warum erstellen Sie MemoryStream? Erstellen Sie FileStream und speichern Sie den Encoder direkt. –

Antwort

11

Ersetzen Sie die ersten vier Zeilen mit diesen Linien

  Rect bounds = VisualTreeHelper.GetDescendantBounds(canvas); 
      double dpi = 96d; 


      RenderTargetBitmap rtb = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, dpi, dpi, System.Windows.Media.PixelFormats.Default); 


      DrawingVisual dv = new DrawingVisual(); 
      using (DrawingContext dc = dv.RenderOpen()) 
      { 
       VisualBrush vb = new VisualBrush(canvas); 
       dc.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size)); 
      } 

      rtb.Render(dv); 

ich diesen Artikel http://mcleodsean.wordpress.com/2008/10/07/bitmap-snapshots-of-wpf-visuals/ (nähere Erklärung) gefolgt und in der Lage, die Leinwand ohne Ränder zu speichern.

+0

Dies ist die Lösung, die für mich funktioniert, vielen Dank – Daniel

+0

Hatte das gleiche Problem, mit dieser Lösung gelöst! – FrancescoDS

+0

Funktioniert wie ein Zauber, danke. – Anders