Get a bitmap image from a Control view

后端 未结 2 684
迷失自我
迷失自我 2020-11-27 18:19

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 c

相关标签:
2条回答
  • 2020-11-27 18:43

    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.

    0 讨论(0)
  • 2020-11-27 18:44

    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;
    }
    
    0 讨论(0)
提交回复
热议问题