VTK版本:2.4
这是一个很old的版本,1999年的代码,或许和新版本中的结构不太一样,但它代码少,结构简单,编译迅速,容易下手。假设我要从0学起,而且,有充裕的时间弄懂封装代码后面的真相。
vtk的pipeline结构,基本上是从Reader开始的,数据流么,总是要有个源头的,so,我们从BMP的读取开始。
类名:vtkBMPReader
追踪:vtkBMPReader -> vtkImageReader -> vtkImageSource -> vtkImageData -> vtkStructuredPoints -> vtkDataSet -> vtkDataObject -> vtkObject(基类)
----------------------------我是分隔符--------------------------------
接下来,从基类开始理顺序。
vtkObject:抽象基类。应该是VTK最基础的class之一,其中实现了New, Delete, Modifiedm, 还有命令行中的Warning。
vtkDataObject:实现了Initialize。这里涉及到两个class:vtkSource 和 vtkFieldData,vtkSource用来执行Update;vtkFieldData用来处理数据,是一个mXn的矩阵模型。
vtkDataSet:抽象类。用来定义几个接口(Bounds,ScalarRange,Center,Length,NumberOfPoints,NumberOfCells)。
vtkStructuredPoints:vtkDataSet的具体类。实现了一个结构化点集,包括volumes (voxel data) and pixmaps。
vtkImageData:这个恐怕是vtk中最常用的数据类了,直接指向保存数据的内存空间,其存在的目的在于实现pipeline,所以经常是xxx->GetOutput()。
vtkImageSource:所有图像源和滤波器的超类,主要用来实现Update。(这个就是pipeline连接好后,只需要在代码的末尾update下的原因)
vtkImageReader:目前最接近地气的类,实现了从磁盘读取一个文件,经常用到的SetFileName和SetFilePrefix,输入的都是char *。
vtkBMPReader:解析BMP图像~
上面这一堆类,看起来好复杂,其实现的功能就一个:把磁盘上的BMP文件读进内存,并转换为vtkImageData格式存在内存中。只是一层又一层的马甲而已。别问为什么要这么做,VTK是一颗大树,我们只是从中抽取一根小树枝。
----------------------------我是分隔符--------------------------------
接下来,开始动手,自己实现一个bmpreader,读取一幅BMP格式的2D图像,然后转换成vtkImageData格式。
需求分析:
1、C++输入IO接口
2、解析BMP
3、转换格式继续,从1开始捋代码。
vtkBMPReader中用到一个很重要的头文件:#include <stdio.h>:stdio == standard input output
几个关键词:fopen,fgetc,fclose,sizeof,
----------------------------我是分隔符--------------------------------
vtkImageData是VTK中最常见的图像数据格式,BMP是windows下最常用格式,本文介绍BMP和vtkImageData的互相转换。这里脱离工具包的封装,手动原生态转换。
vtkImageCache 将 vtkImageReader 与 vtkImageData 联系起来,(神来之笔)。
vtkBMPReader是vtkImageReader 的子类,vtkImageReader 则是vtkImageSource的子类。
逐渐摆脱vtkBMPReader模式的束缚,不通过VTK管道流,以插件模式插入VTK管道。
1、获得BMP图像的各种信息:GetWidth,GetHeight,GetBitCount,Get*
2、构建一个同等大小的vtkImageData
3、设置vtkImageData的像素通道
4、将对应的像素逐个填充进这个vtkImageData中
5、done
char readPath[]="D:\\img\\image_temp.bmp";
bmpreader *pReader = new bmpreader;
pReader->readBmp(readPath);
vtkImageData *bmp_img_data = vtkImageData::New();
bmp_img_data ->SetDimensions(pReader->GetWidth(),pReader->GetHeight(),1);
bmp_img_data ->SetScalarTypeToUnsignedChar();
bmp_img_data ->SetNumberOfScalarComponents(1);
bmp_img_data ->AllocateScalars();
unsigned char *ptr = (unsigned char*)bmp_img_data ->GetScalarPointer();
for(int i=0; i<pReader->GetWidth()*pReader->GetHeight()*1; i++)
{
*ptr ++ = *(pReader->GetOutput()+ i);
}
//vtkBMPReader *bmp_img_reader = vtkBMPReader::New();
//bmp_img_reader->SetFileName(readPath);
//bmp_img_reader->Update();
vtkBMPWriter *bmp_img= vtkBMPWriter::New();
//bmp_img->SetInput(bmp_img_reader->GetOutput());
bmp_img->SetInput(bmp_img_data );
bmp_img->SetFileName("d:\\111.bmp");
bmp_img->Write();
以上代码段中,自定义部分与vtkBMPReader的功能相同:读取BMP到内存,并成功将其传化为vtkimagedata。这里是不是隐隐约约看到所谓的vtkimagedata只是一个封装很好的普通数据结构而已?早晚一天会看到真相,呵呵。