如何使用 vtkImageImport 创建 vtkImageData,该导入在 vtkImageImport 删除后仍

How to create vtkImageData using vtkImageImport that persists after vtkImageImport deletion?

本文关键字:vtkImageImport 删除 导入 何使用 创建 vtkImageData      更新时间:2023-10-16

>我有一个简单的 C 指针,其中包含一些 RGBA 图像数据,我想将其用作vtkImageData,以添加为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的需要。

您是否尝试过深度复制输出?

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 没有测试此代码,但它应该可以工作。您需要在深度复制之前进行更新,以便图像导入实际完成其工作。

这似乎不是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 );
}
}