从“控件”视图中获取位图图像

时间:2010-03-26 10:11:14

标签: wpf

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

有一种简单的方法吗?

提前致谢。

3 个答案:

答案 0 :(得分:33)

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

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

嗯,那个部分很简单,现在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);

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

答案 1 :(得分:9)

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

Jaime Rodriguez有一段很好的代码可以在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;
}

答案 2 :(得分:1)

这在您的代码隐藏中: (或传入窗口。)

不是我的,而是我的大杂烩,还有谷歌搜索。适用于 .Net 5 和 WPF

    public void RenderThisWindow(string fullPngPath)
    {
        Image myImage = new Image();
        
        DrawingVisual drawingVisual = new DrawingVisual();

        RenderTargetBitmap bmp = new RenderTargetBitmap((int)Width, (int)Height, 120, 96, PixelFormats.Pbgra32);
        bmp.Render(this);
        myImage.Source = bmp;

        SaveToPng(this, fullPngPath);
    }
    
    private void SaveToPng(FrameworkElement visual, string fileName)
    {
        var encoder = new PngBitmapEncoder();
        SaveUsingEncoder(visual, fileName, encoder);
    }
    
    private void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
    {
        RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.Width, (int)visual.Width, 96, 96, PixelFormats.Pbgra32);
        bitmap.Render(visual);
        BitmapFrame frame = BitmapFrame.Create(bitmap);
        encoder.Frames.Add(frame);

        using (var stream = File.Create(fileName))
        {
            encoder.Save(stream);
        }
    }