使用 RenderTargetBitmap 的 WPF 画布区域的快照

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14118003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:52:00  来源:igfitidea点击:

Snapshot of an WPF Canvas Area using RenderTargetBitmap

wpfpngsnapshotrendertargetbitmap

提问by Amar

I want to create a Snapshot of the Canvas Area in my Application. I'm using Visual brush to get the Snapshot and saving the same using PngEncoder. But the resulting PNG is just a empty black image. I'm not sure the issue is with the BitmapSource created or the PNGEncoder issue. Here is the code I'm using to obtain the same.

我想在我的应用程序中创建画布区域的快照。我正在使用 Visual Brush 来获取快照并使用 PngEncoder 进行保存。但生成的 PNG 只是一个空的黑色图像。我不确定问题出在创建的 BitmapSource 还是 PNGEncoder 问题上。这是我用来获得相同的代码。

public void ConvertToBitmapSource(UIElement element)
{
    var target = new RenderTargetBitmap((int)(element.RenderSize.Width), (int)(element.RenderSize.Height), 96, 96, PixelFormats.Pbgra32);
    var brush = new VisualBrush(element);

    var visual = new DrawingVisual();
    var drawingContext = visual.RenderOpen();


    drawingContext.DrawRectangle(brush, null, new Rect(new Point(0, 0),
    new Point(element.RenderSize.Width, element.RenderSize.Height)));

    drawingContext.Close();

    target.Render(visual);

    PngBitmapEncoder encoder = new PngBitmapEncoder();
    BitmapFrame outputFrame = BitmapFrame.Create(target);
    encoder.Frames.Add(outputFrame);
    using (FileStream file = File.OpenWrite("TestImage.png"))
    {
         encoder.Save(file);
    }

}   

回答by Clemens

Not sure why exactly your code isn't working. This works:

不确定为什么您的代码无法正常工作。这有效:

public void WriteToPng(UIElement element, string filename)
{
    var rect = new Rect(element.RenderSize);
    var visual = new DrawingVisual();

    using (var dc = visual.RenderOpen())
    {
        dc.DrawRectangle(new VisualBrush(element), null, rect);
    }

    var bitmap = new RenderTargetBitmap(
        (int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default);
    bitmap.Render(visual);

    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bitmap));

    using (var file = File.OpenWrite(filename))
    {
        encoder.Save(file);
    }
}

回答by ILIA BROUDNO

Thank you both for the question and the answer.

感谢您的提问和回答。

For the benefit of the others looking for the same answer

为了其他寻求相同答案的人的利益

I found that Clemens way leaves a black band in the image with the image shifted either down or right. As if it was not rendering the element at the correct position in the bitmap.

我发现 Clemens 方式会在图像中留下一条黑带,图像向下或向右移动。好像它没有在位图中的正确位置渲染元素。

So I had to use the VisualBrush as Amar suggested.

所以我不得不按照 Amar 的建议使用 VisualBrush。

Here is the code that worked for me:

这是对我有用的代码:

    RenderTargetBitmap RenderVisual(UIElement elt)
    {
        PresentationSource source = PresentationSource.FromVisual(elt);
        RenderTargetBitmap rtb = new RenderTargetBitmap((int)elt.RenderSize.Width,   
              (int)elt.RenderSize.Height, 96, 96, PixelFormats.Default);

        VisualBrush sourceBrush = new VisualBrush(elt);
        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();
        using (drawingContext)
        {
            drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), 
                  new Point(elt.RenderSize.Width, elt.RenderSize.Height)));
        }
        rtb.Render(drawingVisual);

        return rtb;
    }