如何使用vtkImageImport创建vtkImageData在vtkImageImport删除后仍然存在?

时间:2017-08-21 13:17:09

标签: c++ c vtk

我有一个简单的C指针,其中包含一些我希望用作vtkImageData的RGBA图像数据作为纹理添加到vtkActor。要做到这一点,我有一些代码,如

vtkSmartPointer<vtkActor> myActor; // initialized elsewhere

setActorTexture( unsigned char* pData, int width, int height )
{
    vtkSmartPointer<vtkImageData> imageData;

    if( pData )
    {
        vtkSmartPointer<vtkImageImport> imageImport = vtkSmartPointer<vtkImageImport>::New();
        imageImport->SetWholeExtent( 0, width - 1, 0, height - 1, 0, 0 );
        imageImport->SetDataExtentToWholeExtent();
        imageImport->SetDataScalarTypeToUnsignedChar();
        imageImport->SetNumberOfScalarComponents( 4 );
        imageImport->CopyImportVoidPointer( pData, width * height * 4 );

        imageData = vtkSmartPointer<vtkImageData>::New();
        imageData = imageImport->GetOutput();
    }

    if( imageData != nullptr )
    {
        vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
        texture->SetInputData( imageData );
        myActor->SetTexture( texture );
    }
}

可悲的是,当稍后在渲染中使用图像数据时,这会导致内存异常。一旦imageData对象超出范围,imageImport对象似乎变为无效。

如果imageImport对象超出范围,我怎么能阻止它自己删除? texture->SetInputData()myActor->SetTexture()函数会注册其参数,以便vtkObject正确设置其引用计数。我想我需要做一些事情,以便imageImport也正确设置其引用计数,以反映imageData的需要。

2 个答案:

答案 0 :(得分:0)

您是否尝试过DeepCopy输出?

setActorTexture( unsigned char* pData, int width, int height )
{
    vtkSmartPointer<vtkImageData> imageData;

    if( pData )
    {
        vtkSmartPointer<vtkImageImport> imageImport = vtkSmartPointer<vtkImageImport>::New();
        imageImport->SetWholeExtent( 0, width - 1, 0, height - 1, 0, 0 );
        imageImport->SetDataExtentToWholeExtent();
        imageImport->SetDataScalarTypeToUnsignedChar();
        imageImport->SetNumberOfScalarComponents( 4 );
        imageImport->CopyImportVoidPointer( pData, width * height * 4 );

        imageData = vtkSmartPointer<vtkImageData>::New();
        imageImport->Update(); //important
        imageData->DeepCopy( imageImport->GetOutput() );
    }

    if( imageData != nullptr )
    {
       vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
       texture->SetInputData( imageData );
       myActor->SetTexture( texture );
    }
}

请注意,id没有测试此代码,但它应该可以正常工作。您需要在深度复制之前进行更新,以便ImageImport实际完成其工作。

答案 1 :(得分:0)

vtkImageImport本身似乎不是问题,而是渲染管道不接受RGBA图像。

vtkImageImport :: SetNumberOfScalarComponents()的文档指出应指定3个组件(对于RGB图像):https://vtk.org/doc/release/7.1/html/classvtkImageImport.html#a6f505565fa53cd850e95256deb22275d

因此,如下所示,加载4分量图像并使用vtkImageExtractComponents剥离Alpha分量可能会有所帮助:

setActorTexture( unsigned char* pData, int width, int height )
{
    vtkSmartPointer<vtkImageData> imageData;

    if( pData )
    {
        vtkSmartPointer<vtkImageImport> imageImport = vtkSmartPointer<vtkImageImport>::New();
        imageImport->SetWholeExtent( 0, width - 1, 0, height - 1, 0, 0 );
        imageImport->SetDataExtentToWholeExtent();
        imageImport->SetDataScalarTypeToUnsignedChar();
        imageImport->SetNumberOfScalarComponents( 4 );
        imageImport->CopyImportVoidPointer( pData, width * height * 4 );
        imageImport->Update();

        // remove alpha channel
        vtkSmartPointer<vtkImageExtractComponents> extract = vtkSmartPointer<vtkImageExtractComponents>::New();
        extract->SetComponents(0, 1, 2);    // RGB components
        extract->SetInputData(imageImport->GetOutput());
        extract->Update();

        imageData = vtkSmartPointer<vtkImageData>::New();
        imageData = extract->GetOutput();
    }

    if( imageData != nullptr )
    {
        vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
        texture->SetInputData( imageData );
        myActor->SetTexture( texture );
    }
}