VTK.js 由于不能直接读取DICOM格式的文件,需要用到Itk.js。
安装itk.js
npm install itk
基于vite-vue 来配置相应的打包环境和config配置文件,具体如下:
文件vite.config.ts
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import path from "path";
const itkConfig = path.resolve(__dirname, "src", "itkConfig.js");
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
import copy from "rollup-plugin-copy";
const base = "/";
// https://vitejs.dev/config/
export default defineConfig({
base: base,
plugins: [
vue(),
vueJsx(),
copy({
targets: [
{ src: "node_modules/itk-wasm/dist/web-workers", dest: "dist/itk" },
{
src: "node_modules/itk-image-io",
dest: "dist/itk",
rename: "image-io",
},
{
src: "node_modules/itk-mesh-io",
dest: "dist/itk",
rename: "mesh-io",
},
],
hook: "writeBundle",
}),
],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
"../itkConfig.js": itkConfig,
"../../itkConfig.js": itkConfig,
},
},
});
src 根目录下面建立文件itkConfig.js
const itkConfig = {
pipelineWorkerUrl: "/itk/web-workers/min-bundles/pipeline.worker.js",
imageIOUrl: "/itk/image-io",
meshIOUrl: "/itk/mesh-io",
pipelinesUrl: "/itk/pipelines",
};
export default itkConfig;
具体可参考官方文档:
Using itk-wasm in a web browser application via Vitewasm.itk.org/examples/vite.html
基于VTK的继承写法来仿照itkDICOMReader 的仿照写法 如下所示:
需要一个newInstance 和extend 的继承如下所示:
export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
macro.obj(publicAPI, model);
macro.algo(publicAPI, model, 0, 1);
macro.setGet(publicAPI, model, ["fileName", "arrayName"]);
vtkITKDicomImageReader(publicAPI, model);
}
export const newInstance = macro.newInstance(extend, "vtkITKDicomImageReader");
export default { newInstance, extend };
以上为基于VTK的继承写法 在此里面加上itk的api,利用itk-wasm 里面的readImageDICOMFileSeries 来读取序列图 。
获取后的image 是itk的数据 所以还需要vtk来做一次转换,基于vtkITKHelper中的convertItkToVtkImage 即可
import macro from "@kitware/vtk.js/macros";
import { readImageDICOMFileSeries } from "itk-wasm";
import vtkITKHelper from "@kitware/vtk.js/Common/DataModel/ITKHelper";
function vtkITKDicomImageReader(publicAPI, model) {
// Set our className
model.classHierarchy.push("vtkITKDicomImageReader");
// Returns a promise to signal when image is ready
publicAPI.readFileSeries = (files, fileName) => {
if (!files || !files.length || files === model.files) {
return Promise.resolve();
}
if (fileName && fileName !== model.fileName) {
model.fileName = fileName;
}
model.files = files;
return readImageDICOMFileSeries(files).then(({ webWorker, image }) => {
const imageData = vtkITKHelper.convertItkToVtkImage(image, {
scalarArrayName: model.arrayName || getArrayName(model.fileName),
});
model.output[0] = imageData;
publicAPI.modified();
return imageData;
});
};
publicAPI.requestData = (/* inData, outData */) => {
publicAPI.readFileSeries(model.files, model.fileName);
};
}
以上是封装了一个DICOMReader读取数据器的实现思路。 下一篇文章将会基于这个读取器来实现数据的渲染 3D模型。