I have a WPF window with a ScrollViewer control containing many child controls that extend vertically. When a user clicks a button located at the bottom of the ScrollViewer I would like all the content (currently in view and out of view) to be saved as an image.
I am using the following code which I have adapted from examples showing how to save the content of a Window:
public static void SaveForm(ScrollViewer container, string filename)
{
const int dpi = 96;
var rtb = new RenderTargetBitmap(
(int)container.ExtentWidth, //width
(int)container.ExtentHeight, //height
dpi, //dpi x
dpi, //dpi y
PixelFormats.Pbgra32 // pixelformat
);
rtb.Render(container);
SaveRTBAsPNG(rtb, filename);
}
private static void SaveRTBAsPNG(RenderTargetBitmap bmp, string filename)
{
var enc = new System.Windows.Media.Imaging.PngBitmapEncoder();
enc.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp));
using (var stm = System.IO.File.Create(filename))
{
enc.Save(stm);
}
}
Currently a PNG is being produced but it only has the currently visible portion of the ScrollViewer. Is there any way I can get the PNG to contain all of the content, including that which needs to be scrolled into view?
Use this with the CONTENT of you scrollviewer as source, not your scrollviewer itself : (It takes a snapshot even if the content is not visible)
public static void SnapShotPNG(this UIElement source, Uri destination, int zoom)
{
try
{
double actualHeight = source.RenderSize.Height;
double actualWidth = source.RenderSize.Width;
double renderHeight = actualHeight * zoom;
double renderWidth = actualWidth * zoom;
RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);
VisualBrush sourceBrush = new VisualBrush(source);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
using (drawingContext)
{
drawingContext.PushTransform(new ScaleTransform(zoom, zoom));
drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
}
renderTarget.Render(drawingVisual);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTarget));
using (FileStream stream = new FileStream(destination.LocalPath, FileMode.Create, FileAccess.Write))
{
encoder.Save(stream);
}
}
catch (Exception e)
{
MessageBox.Show(e);
}
}