vtkWindowToImageFilter导致内存泄漏?

时间:2016-01-08 09:21:01

标签: c# memory-leaks vtk

我编写了一个小工具,可以从不同的摄像机角度创建多个STL的屏幕截图。 vtkWindowToImageFiltervtkWin32OpenGLRenderWindow的内容转换为图像,然后使用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);
   }
}

1 个答案:

答案 0 :(得分:0)

因为我注意到该工具从相同的摄像机视点创建了几个屏幕截图(由在循环外部使用的vtkWindowToImageFilter的SetInput方法引起),我重写了代码以创建vtkWindowToImageFiltervtkPngWriter循环中的foreach。这使我可以在使用它们之后将它们丢弃,从而释放内存。

请注意,在以前版本的代码中,我还尝试在循环结束后立即处置vtkWindowToImageFiltervtkPngWriter,但这似乎没有释放任何内存。不幸的是,我不清楚为什么这不起作用。

当前版本的代码如下所示,并且不会导致内存泄漏,如前所述。

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);
    }
}