I have a MVVM WPF application.
I am trying to capture current content of the window without the Window Form Header and Window Form borders.
I know this is easy to do in a Windows Forms application, here is an example.
I would like to do the same in my WPF application but I am lost. I have found an example here but it captures all the screen.
How can I do this? Also, once captured I need to send it directly to print to the default printer.
So I am trying to do the following without success:
- Capture WPF window content without the Window Form Header and Window Form borders.
- Print this screen capture to default printer without showing any print dialog.
ATTEMPT #1 - ISSUE 1 - Capture screen: Regarding point 1 (capturing content of window) I have done below. SnapShotPNG solution is working perfectly.
TopGrid UI Element in GetSnapshotButton_Click is the grid from which I want to do snapshot its content.
GetJpgImage solution is not working at all. In the snapshot appears black zones. Why?
Solutions extracted from here and here.
private void GetSnapshotButton_Click(object sender, RoutedEventArgs e)
{
var uri = new System.Uri("c:\\Temp\\capture1.png");
SnapShotPNG(TopGrid, uri, 1);
uri = new System.Uri("c:\\Temp\\capture2.jpg");
GetJpgImage(TopGrid, uri, 1, 100);
}
public void SnapShotPNG(UIElement source, Uri destination, int scale)
{
try
{
double actualHeight = source.RenderSize.Height;
double actualWidth = source.RenderSize.Width;
double renderHeight = actualHeight * scale;
double renderWidth = actualWidth * scale;
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(scale, scale));
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);
}
}
///
/// Gets a JPG "screenshot" of the current UIElement
///
/// UIElement to screenshot
/// Scale to render the screenshot
/// JPG Quality
/// Byte array of JPG data
public void GetJpgImage(UIElement source, Uri destination, double scale, int quality)
{
double actualHeight = source.RenderSize.Height;
double actualWidth = source.RenderSize.Width;
double renderHeight = actualHeight * scale;
double renderWidth = actualWidth * scale;
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(scale, scale));
drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
}
renderTarget.Render(drawingVisual);
JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
jpgEncoder.QualityLevel = quality;
jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
using (FileStream stream = new FileStream(destination.LocalPath, FileMode.Create, FileAccess.Write))
{
jpgEncoder.Save(stream);
}
}
ATTEMPT #2 - ISSUE 1 - Capture screen: Using Dymanoid solution works but with one problem: Content does not fit in one page. I am trying now to fit into one page. To fit content into one page I am trying to do what is explained here.
for printing grid cotent (see here):
PrintDialog printDlg = new PrintDialog();
printDlg.PrintVisual(TopGrid, "Grid Printing.");
for printing entire wpf window (see here):
PrintDialog printDlg = new PrintDialog();
printDlg.PrintVisual(this, "Window Printing.");