WPF RenderTargetBitmap缺少元素
我有一个树状视图,在数据模板中显示小图标。我正在尝试使用RenderTargetBitmap将Treeview保存为PNG 图像正确地保存在小数据集上。但是,如果数据集变得太大,一些图标将从最终图像中排除。神奇的数字似乎是200件。树是深还是宽似乎无关紧要,在200个项目之后,图标不会被渲染 添加代码 这是我用来创建图像的代码WPF RenderTargetBitmap缺少元素,wpf,rendertargetbitmap,Wpf,Rendertargetbitmap,我有一个树状视图,在数据模板中显示小图标。我正在尝试使用RenderTargetBitmap将Treeview保存为PNG 图像正确地保存在小数据集上。但是,如果数据集变得太大,一些图标将从最终图像中排除。神奇的数字似乎是200件。树是深还是宽似乎无关紧要,在200个项目之后,图标不会被渲染 添加代码 这是我用来创建图像的代码 RenderTargetBitmap targetBitmap = new RenderTargetBitmap( (int)_t
RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
(int)_treeView.ActualWidth,
(int)_treeView.ActualHeight,
96, 96, PixelFormats.Default);
targetBitmap.Render(_treeView);
添加了屏幕截图
请注意树右侧缺少的图标。
现在,如果我折叠了几个分支,从而隐藏了一些其他图标,那么这些图标就包括在内了。这几乎就像RenderTargetBitmap。Render没有能力渲染所有图标。或者它可能与虚拟面板有关。
这里有一个更仔细的观察。
我立刻注意到你的巨大形象。宽度12000。我很惊讶你竟然如此接近 如MSDN所述,纹理宽度/高度受DirectX纹理限制的限制 XAML视觉树的最大渲染大小受Microsoft DirectX纹理的最大尺寸限制;有关更多信息,请参阅资源限制(Direct3D)。此限制可能因应用程序运行的硬件而异。超过此限制的非常大的内容可能会进行缩放以适应。如果以这种方式应用缩放限制,则可以使用“PixelWidth”和“PixelHeight”属性查询缩放后的渲染大小。例如,10000 x 10000像素的XAML可视树可能会缩放到4096 x 4096像素,这是应用程序运行的硬件强制的特定限制的一个示例。 我怀疑这些事情:
- 虚拟化切断了一些东西——我过去遇到过DataGrid的确切问题,问题是虚拟化。不过你的案子看起来不像
- 纹理过大可能会导致未定义的行为李>
你应该能够计算所有这些东西 对于记录:有一个解决方法 使用临时DrawingVisual,而不是使用RenderTargetBitmap直接渲染视觉效果。使用VisualBrush将视觉绘制到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“瓷砖”,如下所述:
你能帮我试试吗;只需将所有图像设置为2x2图像。你还有200件物品的限制吗?@MeirionHughes哇!有趣。在2x2时,未渲染任何图标。我增加了一点尺寸,然后只有几个图标,比如10个。所以当我问这个问题时,模板被设置为100x100,所以我把它改为150x150,所有的图标都被渲染了!那么到底发生了什么?不知道。。。非常奇怪,我想说你在虚拟化和缓存方面有一些问题。您没有对图像进行任何处理,比如将所有图像存储在同一位图中或其他什么?我是从256x256的内存流创建图像。如果将大小更改为512x512,则渲染的图标会减少。如果更改为100x100,将渲染更多图标。这与更改数据模板大小不同且相反。应用程序中是否显示图标?我的意思不是渲染的图像,只是承载树视图的窗口。这可能是解决方案,但我需要几天的时间来测试。然而,这是一个非常好的提示!正如我在评论中提到的,这与虚拟化无关:虽然最初的海报可能使用了虚拟化,但我肯定没有。我也怀疑这与硬件加速有关,因为RenderTargetBitmap不使用硬件加速。这不是来自RenderTargetBitmap MSDN页面,而是来自MSDN上的其他帖子,其中人们抱怨RenderTargetBitmap的速度;如果我以
64位处理器为目标,我可以成功生成15000x15000
png图像。尝试保存png时,尝试使用30000x30000
图像会产生内存错误。在32位处理器上尝试30000x30000
会在创建RenderTargetBitmap
时产生内存错误。尝试使用60000x60000
图像会在调用Render()
时产生错误。某些设置组合在尝试保存时会生成“general GDI+错误”。我的观点是:资源限制的错误不会被默默地吞没-因此我不认为这是一个资源错误。请附上一个为您生成错误的测试用例,我将告诉您发生错误的原因。(exe和sln)