C#、WPF、Helix Toolkit。我正在尝试从 HelixViewport3D
视口保存图像(如此处所述),但仍然遇到问题。
预期方法:将图像渲染到视口并使用 Viewport3DHelper.SaveBitmap()
或类似的方法简单保存之。
Viewport3DHelper.SaveBitmap(helixPlot.Viewport, @"E:\test.bmp", null, 4, BitmapExporter.OutputFormat.Png);
问题所在:它可以运行,但捕获的图像是空白的。我最好的猜测是Helix Toolkit在异步渲染(?)我保存它的时候没有图像可供抓取。
可能的解决方法1:在渲染完成后响应事件。
问题所在:没有合适的事件可供订阅。可能的解决方法2:添加内联延迟以允许图像在保存之前呈现。(笨重且不可靠,但是将是朝着正确方向迈出的一步)。
Thread.Sleep(2000);
Viewport3DHelper.SaveBitmap(helixPlot.Viewport, @"E:\test.bmp", null, 4, BitmapExporter.OutputFormat.Png);
问题所在:图像只有在我的代码执行完成后才会显示。如果我添加10秒的延迟,我只会多等待10秒钟看到一个空白屏幕。
可能的解决方案3:添加计时器以便渲染图像,然后可以从计时器已过去的事件中保存图像。
System.Timers.Timer timer = new System.Timers.Timer();
...
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timer.Interval = 2000; // two seconds
timer.Start();
....
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
Viewport3DHelper.SaveBitmap(helixPlot.Viewport, @"E:\test.bmp", null, 4, BitmapExporter.OutputFormat.Png);
}
问题所在:尽管图像已成功渲染并可用于使用,但计时器在不同的线程中运行,因此我不能从事件处理程序引用HelixPlot控件。我会收到以下错误信息:System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
可能的解决方法4:使用Timer.SynchronizingObject
在UI线程中运行定时器。
问题所在:在WPF中似乎很难/简单地实现这一点。我可以通过大量的额外代码来做到这一点,目前这可能是我最好的选择,但由于冗长和缺乏稳健性的原因,这似乎不是最优解。
难道没有一种相当简单的方式来实现我想要做的事情吗?
问题的根源似乎是图像直到调用方法完成后才呈现到视口。我真的不明白为什么会这样。
编辑:我在另一个论坛上被告知,Helix Toolkit正在WPF复合渲染线程上进行渲染。然而,在经过一些搜索后,我仍然不知道如何等待此渲染完成。
Dispatcher.Invoke
函数中添加Threading.DispatcherPriority.Render
来正确渲染广告牌。 - j__