我有一个简单的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
的需要。
答案 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 );
}
}