Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a bitmap image from a Control view

Tags:

I would like to "copy to clipboard" what a Control of my WPF app draws on the screen. Therefore, I need to build a bitmap image from my Control current display.

Is there an easy way to do that ?

Thanks in advance.

like image 493
Aurelien Ribon Avatar asked Mar 26 '10 10:03

Aurelien Ribon


2 Answers

I wouldn't call it easy...but the key component is the RenderTargetBitmap, which you can use as follows:

RenderTargetBitmap rtb = new RenderTargetBitmap((int)control.ActualWidth, (int)control.ActualHeight, 96, 96, PixelFormats.Pbgra32); rtb.Render(control); 

Well, that part is easy, now the RTB has the pixels stored internally...but your next step would be putting that in a useful format to place it on the clipboard, and figuring that out can be messy...there are a lot of image related classes that all interact one or another.

Here's what we use to create a System.Drawing.Image, which i think you should be able to put on the clipboard.

PngBitmapEncoder png = new PngBitmapEncoder(); png.Frames.Add(BitmapFrame.Create(rtb)); MemoryStream stream = new MemoryStream(); png.Save(stream); Image image = Image.FromStream(stream); 

System.Drawing.Image (a forms image) cannot interact directly with the RenderTargetBitmap (a WPF class), so we use a MemoryStream to convert it.

like image 119
Bubblewrap Avatar answered Sep 22 '22 18:09

Bubblewrap


If the control you are trying to create a bitmap from is inside a StackPanel it won't work, you will just get an empty image.

Jaime Rodriguez has a good piece of code to get around this on his blog:

private static BitmapSource CaptureScreen(Visual target, double dpiX, double dpiY) {     if (target == null)     {         return null;     }     Rect bounds = VisualTreeHelper.GetDescendantBounds(target);     RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX / 96.0),                                                     (int)(bounds.Height * dpiY / 96.0),                                                     dpiX,                                                     dpiY,                                                     PixelFormats.Pbgra32);     DrawingVisual dv = new DrawingVisual();     using (DrawingContext ctx = dv.RenderOpen())     {         VisualBrush vb = new VisualBrush(target);         ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));     }     rtb.Render(dv);     return rtb; } 
like image 21
Björn Avatar answered Sep 23 '22 18:09

Björn