34

I created a WPF application using the Bing maps WPF control. I would like to be able to screenshot only the Bing maps control.

I use this code to make the screenshot:

// Store the size of the map control
int Width = (int)MyMap.RenderSize.Width;
int Height = (int)MyMap.RenderSize.Height;
System.Windows.Point relativePoint = MyMap.TransformToAncestor(Application.Current.MainWindow).Transform(new System.Windows.Point(0, 0));
int X = (int)relativePoint.X;
int Y = (int)relativePoint.Y;

Bitmap Screenshot = new Bitmap(Width, Height);
Graphics G = Graphics.FromImage(Screenshot);
// snip wanted area
G.CopyFromScreen(X, Y, 0, 0, new System.Drawing.Size(Width, Height), CopyPixelOperation.SourceCopy);

string fileName = "C:\\myCapture.bmp";
System.IO.FileStream fs = System.IO.File.Open(fileName, System.IO.FileMode.OpenOrCreate);
Screenshot.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp);
fs.Close();

My problem:

The Width and Height appear to be bad (false values). The screenshot produced appear to use bad coordinates.

My screenshot:

My screenshot

What I expect:

Desired screenshot

Why do I get this result? I tried in Release mode, and without Visual Studio, result is the same.

D3vtr0n
  • 2,774
  • 3
  • 33
  • 53
Walter Fabio Simoni
  • 5,671
  • 15
  • 55
  • 80

1 Answers1

63

A screenshot is a shot of the screen... everything on the screen. What you want is to save an image from a single UIElement and you can do that using the RenderTargetBitmap.Render Method. This method takes a Visual input parameter and luckily, that is one of the base classes for all UIElements. So assuming that you want to save a .png file, you could do this:

RenderTargetBitmap renderTargetBitmap = 
    new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(yourMapControl); 
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (Stream fileStream = File.Create(filePath))
{
    pngImage.Save(fileStream);
}
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • 2
    What if I want to show this `pngImage` in `image` control instead of saving `pngImage` – Uzair Ali Jan 13 '15 at 19:01
  • 1
    @UzairAli, that's far simpler. Just use the control that you want to display as the `Visual` of a `VisualBrush`. See the [`VisualBrush` Class](http://msdn.microsoft.com/en-us/library/system.windows.media.visualbrush(v=vs.110).aspx) page on MSDN for further information. – Sheridan Jan 14 '15 at 08:52
  • 1
    `VisualTreeHelper.GetDescendantBounds` will help you get the dimensions for any `Visual`. It returns `Rect`, whose `Width` and `Height` are doubles; you need convert them using `Convert.ToInt32`. – Palec Sep 12 '16 at 16:39
  • 2
    It's worth mentioning that `PixelFormats.Pbgra32` is the only supported format here. You may specify it more implicitly as `PixelFormats.Default`. – Palec Sep 12 '16 at 16:41
  • I'm trying to use this code with datagrid but I got blank image. Isn't datagrid supported? – Denis Aug 23 '17 at 15:21
  • 1
    int width = Convert.ToInt32(dtgEvolucaoPendenciasDiretoria.ActualWidth); int height = Convert.ToInt32(dtgEvolucaoPendenciasDiretoria.ActualHeight); RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); PngBitmapEncoder pngImage = new PngBitmapEncoder(); renderTargetBitmap.Render(dtgEvolucaoPendenciasDiretoria); pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); using (Stream fileStream = File.Create(@"D:\Users\dtgEvolucaoPendenciasDiretoria.bmp")) { pngImage.Save(fileStream); } – Denis Aug 23 '17 at 15:23
  • Sorry, I don't know... I've never tried it. If it's not too late, try asking a new question and add a link to this one for background information. – Sheridan Sep 12 '17 at 11:16
  • @Sheridan How to do it in MVVM? – grv_9098 Apr 27 '20 at 19:50
  • @grv_9098, there is no UI-based code in my example. You can call that from your View Models, although I'd put that code into some kind of a Service or Manager class that the View Models have access to. – Sheridan May 27 '20 at 15:54
  • I want to take screenshot from a windows form host but above answer does not take of it. How can I take screenshot from a windows form host? – Mohammad reza Kashi Mar 14 '21 at 09:06
  • @MohammadrezaKashi, if you read this answer, you will see that despite the question title, it does not relate to taking screenshots. Please ask a new question. Thanks. – Sheridan Mar 15 '21 at 16:57