WPF RenderTargetBitmap缺少元素

时间:2013-03-12 18:18:24

标签: wpf rendertargetbitmap

我有一个TreeView,数据模板中显示了小图标。我尝试使用RenderTargetBitmap将Treeview保存为PNG。

图像可以正确保存在小数据集上。但是,如果数据集变得太大,则会从最终图像中排除某些图标。神奇的数字似乎是200项。如果树很深或很宽,在200个项目之后,图标不会被渲染,这似乎并不重要。

已添加代码

所以这是我用来创建图像的代码。

        RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
            (int)_treeView.ActualWidth,
            (int)_treeView.ActualHeight,
            96, 96, PixelFormats.Default);

        targetBitmap.Render(_treeView);

添加了屏幕截图

注意树右侧缺少图标。 Screen shot of missing icons

现在,如果我折叠了几个分支,从而隐藏了其他一些图标,那么这些图标就会被包含在内。它几乎像RenderTargetBitmap.Render没有能力渲染所有的图标。或者它可能与虚拟面板有关。 Screen shot of included icons

这是仔细看看。 enter image description here

2 个答案:

答案 0 :(得分:4)

我立即注意到你有巨大的形象。宽度12000.我很惊讶你甚至接近了。

正如MSDN所述,纹理宽度/高度受DirectX纹理限制的限制。

XAML可视化树的最大渲染大小受Microsoft DirectX纹理的最大尺寸限制;有关更多信息,请参阅资源限制(Direct3D)。此限制可能因应用程序运行的硬件而异。超出此限制的超大内容可能会缩放以适应。如果以这种方式应用缩放限制,则可以使用PixelWidth和PixelHeight属性查询缩放后的渲染大小。例如,10000乘10000像素的XAML可视化树可以缩放到4096乘4096像素,这是应用程序运行的硬件强制的特定限制的示例。 http://msdn.microsoft.com/library/windows/apps/dn298548

我怀疑这些事情:

  • 虚拟化切断了一些事情 - 我在过去使用DataGrid遇到了确切的问题,问题是虚拟化。你的情况似乎不一样。
  • 纹理太大会导致未定义的行为。

您可以尝试禁用硬件加速。这件事导致很少的核心错误。 http://msdn.microsoft.com/en-us/library/system.windows.media.renderoptions.processrendermode.aspx

除此之外 - 它会很棘手,但我很确定它会很好地运作:

1)从根对象开始,递归遍历根对象子节点,直到找到小于1000 x 1000的对象。使用RenderTargetBitmap(BMP)拍摄它并将其合并到IN-MEMORY-BMP 。为每个孩子做。

你应该能够计算所有这些东西。

答案 1 :(得分:0)

对于记录:有一种解决方法。

不使用RenderTargetBitmap直接渲染Visual,而是使用临时DrawingVisual。使用VisualBrush将Visual绘制到DrawingVisual中,然后将RenderTargetBitmap与DrawingVisual一起使用。

像这样:

    public BitmapSource RenderVisualToBitmap(Visual visual)
    {
        var contentBounds = VisualTreeHelper.GetContentBounds(visual);

        var drawingVisual = new DrawingVisual();
        using (var drawingContext = drawingVisual.RenderOpen())
        {
            var visualBrush = new VisualBrush(visual);
            drawingContext.DrawRectangle(visualBrush, null, contentBounds);
        }

        var renderTargetBitmap = new RenderTargetBitmap((int)contentBounds.Width, (int)contentBounds.Height, 96, 96, PixelFormats.Default);
        renderTargetBitmap.Render(drawingVisual);

        return renderTargetBitmap;
    }

但请注意,随着VisualBrush变大,生成的图像越来越模糊(使用高DPI渲染时)。要解决此问题,请使用一系列较小的VisualBrush“磁贴”,如下所述: https://srndolha.wordpress.com/2012/10/16/exported-drawingvisual-quality-when-using-visualbrush/