从"控件"视图中获取位图图像

Aur*_*bon 21 wpf

我想"复制到剪贴板" Control我的WPF应用程序在屏幕上绘制的内容.因此,我需要从Control当前显示中构建一个位图图像.

有一个简单的方法吗?

提前致谢.

Bub*_*rap 35

我不会称之为简单......但关键组件是RenderTargetBitmap,您可以按如下方式使用它:

RenderTargetBitmap rtb = new RenderTargetBitmap((int)control.ActualWidth, (int)control.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(control);
Run Code Online (Sandbox Code Playgroud)

好吧,那个部分很简单,现在RTB内部存储了像素......但是你的下一步就是将它放在一个有用的格式中,将它放在剪贴板上,并确定它可能是凌乱的...有一个许多与图像相关的类都会相互交互.

这是我们用来创建System.Drawing.Image的东西,我认为你应该能够放在剪贴板上.

PngBitmapEncoder png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(rtb));
MemoryStream stream = new MemoryStream();
png.Save(stream);
Image image = Image.FromStream(stream);
Run Code Online (Sandbox Code Playgroud)

System.Drawing.Image(表单图像)无法直接与RenderTargetBitmap(WPF类)交互,因此我们使用MemoryStream对其进行转换.

  • 值得注意的是,虽然这适用于普通的WPF组件,但是只是从不同的空域(如Webbrowser控件)包装组件的任何特殊控件都与RenderTargetBitmap不兼容. (5认同)
  • 谢谢过去的自己!八年多以后,我又想将WPF控件保存到流中。但是我只是不记得它是如何工作的。因此,我用它搜索了一下,令我惊讶的是,我最终阅读了自己的答案。:D (2认同)

Bjö*_*örn 9

如果您尝试创建位图的控件位于其中StackPanel,则无法使用,您将获得一个空图像.

Jaime Rodriguez有一段很好的代码可以在他的博客上解决这个问题:

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;
}
Run Code Online (Sandbox Code Playgroud)