【发布时间】:2014-12-10 04:40:36
【问题描述】:
没想到
RenderTargetBitmap.Render(visual)
有任何副作用摘录更改位图数据本身。看起来这不是真的。在一些丑陋的渲染伪影开始发生之前,我无法重复超过 60 次。
如何在 WPF 中正确渲染大量精灵?下面是重现问题的代码。
我以这种方式生成精灵:
BitmapSource Sprite()
{
var bitmap = new RenderTargetBitmap(
500, 500,
96, 96,
PixelFormats.Default);
var visual = new DrawingVisual();
var rect = new Rect(
new Size(
bitmap.Width,
bitmap.Height));
using (DrawingContext context = visual.RenderOpen())
context.DrawLine(
new Pen(Brushes.Red, 100),
rect.TopLeft,
rect.BottomRight);
bitmap.Render(visual);
bitmap.Freeze();
return bitmap;
}
这是渲染其中许多的画布:
public BitmapSource Canvas
{
get
{
var bitmap = new RenderTargetBitmap(
1980, 1080,
96, 96,
PixelFormats.Default);
var tiles = 70;
for (int i = 0; i < tiles; i++)
{
var visual = new DrawingVisual();
var rect = new Rect(
bitmap.Width / tiles * i,
0,
bitmap.Width / tiles,
bitmap.Height);
using (DrawingContext context = visual.RenderOpen())
context.DrawImage(Sprite(), rect);
bitmap.Render(visual);
}
bitmap.Freeze();
return bitmap;
}
}
我可以在数据绑定到 Canvas 属性时看到这张奇怪的图片...
【问题讨论】:
-
为什么不将这 70 个图块渲染到一个 DrawingVisual 中,然后只调用一次 bitmap.Render 呢?您只需将
for循环移动到using (DrawingContext ...)块中。您还可以通过将线条直接绘制到“外部”DrawingContext 来完全保存“内部”RenderTargetBitmaps。 -
我无法直接渲染图块,因为这意味着单个视觉对象同时保持对 70 个或更多位图的引用。我会用完内存。不幸的是,我确实需要“内部”RenderTargetBitmaps,因为 Tiles 是我的应用程序的输入栅格数据。
-
1) 我无法重现您的问题,即使使用
tiles = 2000。 2) 在单个 Visual 中保留对精灵的所有引用时,我可以重现内存不足异常 - 但大约 855 个图块而不是 70 个图块。您使用的是哪种图形硬件? -
它看起来像一个版本的东西。 .NET Framework 4.0 或更高版本有这个问题。
-
我可以在 Win 8.1 上重现(针对 x86 和 x64)。即使绘制一个存储的精灵(每次都不是不同的)......在大约 70 次迭代时,它开始在您的代码中显示工件。