我编写了一个小工具,可以从不同的摄像机角度创建多个STL的屏幕截图。 vtkWindowToImageFilter
将vtkWin32OpenGLRenderWindow
的内容转换为图像,然后使用vtkPngWriter
将图像写入文件。
我注意到该工具的内存使用情况随着每个屏幕截图而不断上升。经过一些调试后,我发现导致内存上升的代码行在某些时候没有被释放
windowToImageFilter.Update();
有谁知道我是否应该释放vtkWindowToImageFilter
使用的内存?
这是一个完整的功能,可以为一组STL创建不同摄像机角度的屏幕截图。
public void makeImage(vtkRenderWindow window, vtkRenderer renderer, string filePrefix="")
{
if (_parts.Count == 0)
return;
// Make cameras
Cameras cameras = new Cameras(_axial, _coronal, _sagittal, _parts[0].center, _parts[0].zoomfactor);
// VTK
// Setup vtkPNGwriter
vtkPNGWriter writer = vtkPNGWriter.New();
// Setup window to image filter
vtkWindowToImageFilter windowToImageFilter = vtkWindowToImageFilter.New();
windowToImageFilter.SetInput(window);
windowToImageFilter.SetMagnification(2); // set the resolution of the output image (3 times the current resolution of vtk render window)
foreach (string camName in cameraNames)
{
vtkCamera cam = cameras.getCameraByName(camName);
if (cam == null)
continue;
// Skip already created screenshots
if (File.Exists(getFilename(camName,filePrefix)))
continue;
// Clear renderer
renderer.RemoveAllViewProps();
// Show parts
this.show(renderer);
// Set camera
renderer.SetActiveCamera(cam);
renderer.GetActiveCamera().SetClippingRange(1.0, 1000);
window.Render();
// Update window to image filter
windowToImageFilter.Update();
// Write to png
writer.SetFileName(tempFile);
writer.SetInput(windowToImageFilter.GetOutput());
writer.Write();
// Crop png image
Bitmap img = new Bitmap(tempFile);
Bitmap imgCrop = cropImage(img);
imgCrop.MakeTransparent(Color.White);
imgCrop.Save(getFilename(camName,filePrefix));
// Dispose images (necessary to avoid memory filling)
img.Dispose();
imgCrop.Dispose();
// Delete temporary file
File.Delete(tempFile);
}
}
答案 0 :(得分:0)
因为我注意到该工具从相同的摄像机视点创建了几个屏幕截图(由在循环外部使用的vtkWindowToImageFilter
的SetInput方法引起),我重写了代码以创建vtkWindowToImageFilter
和vtkPngWriter
循环中的foreach
。这使我可以在使用它们之后将它们丢弃,从而释放内存。
请注意,在以前版本的代码中,我还尝试在循环结束后立即处置vtkWindowToImageFilter
和vtkPngWriter
,但这似乎没有释放任何内存。不幸的是,我不清楚为什么这不起作用。
当前版本的代码如下所示,并且不会导致内存泄漏,如前所述。
public void makeImage(vtkRenderWindow window, vtkRenderer renderer,string filePrefix="")
{
if (_parts.Count == 0)
return;
// Make cameras
Cameras cameras = new Cameras(_axial, _coronal, _sagittal, _parts[0].center, _parts[0].zoomfactor);
foreach (string camName in cameraNames)
{
vtkCamera cam = cameras.getCameraByName(camName);
if (cam == null)
continue;
// Skip already created screenshots
if (File.Exists(getFilename(camName, filePrefix)))
continue;
// Clear renderer
renderer.RemoveAllViewProps();
// Show parts
this.show(renderer);
// Set camera
renderer.SetActiveCamera(cam);
renderer.GetActiveCamera().SetClippingRange(1.0, 1000);
window.Render();
// Update window to image filter
vtkWindowToImageFilter windowToImageFilter = vtkWindowToImageFilter.New();
windowToImageFilter.SetMagnification(4); // set the resolution of the output image (3 times the current resolution of vtk render window)
windowToImageFilter.SetInput(window);
// Write to png
vtkPNGWriter writer = vtkPNGWriter.New();
writer.SetInputConnection(windowToImageFilter.GetOutputPort());
writer.SetFileName(tempFile);
writer.Write();
// Dispose pipeline parts
windowToImageFilter.Dispose();
writer.Dispose();
// Crop png image
Bitmap img = new Bitmap(tempFile);
Bitmap imgCrop = cropImage(img, squareImages);
imgCrop.MakeTransparent(Color.White);
imgCrop.Save(getFilename(camName,filePrefix));
// Dispose images (necessary to avoid memory filling)
img.Dispose();
imgCrop.Dispose();
// Delete temporary file
File.Delete(tempFile);
}
}