Saving a canvas to png C# wpf

14,051

Replace the first four lines with these lines

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);

I have followed this article http://mcleodsean.wordpress.com/2008/10/07/bitmap-snapshots-of-wpf-visuals/ (for more explanation) and able to save the canvas without margins.

Share:
14,051

Related videos on Youtube

Daniel
Author by

Daniel

Updated on June 04, 2022

Comments

  • Daniel
    Daniel almost 2 years

    So I am trying to take a snapshot of my canvas in WPF C# so that I can save it out as a png. The image saves incorrectly at present as it is including the left and top margins.

    This is what I have:

    create a rectangle for the size of the canvas. if canvas.Margin.Left and Top are set to 0 then the saved image is of the correct size but the offset still occurs and thus cuts the bottom and right edges. Being set the Margin.Left and Top still causes the offset to occur but the whole image is saved but at the wrong size (margin.Left + ActualWidth) rather than just ActualWidth

    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);
    }