vtkITKImageReader on NIFTI (.nii) file format

Hi there,

I’m attempting to load a basic NIFTI file into vtk.js and running into some issues. I have read the .nii file into an Array Buffer (res in the excerpts below) and am unable to render it. In both these attempts, the result of niftiReader.parseAsArrayBuffer(res) then niftiReader.getOutputData() results in undefined.

Documentation for the vtkITKImageReader is a little sparse, so I have been using the following resources, but none of which are particularly up to date. I am using vtk.js v17.17.2.

  • This demo has a working example of loading a .nrrd file using the vtkITKImageReader I am also attempting to use, but they are using vtk.js v13.4.2
  • This forum is where the above demo originated from
  • This forum where it is mentioned that setting the file name is important but it’s not clear to me how/why this is the case.
import readImageArrayBuffer from "itk/readImageArrayBuffer";
import vtkITKImageReader from "@kitware/vtk.js/IO/Misc/ITKImageReader";
... // all other imports required

vtkITKImageReader.setReadImageArrayBufferFromITK(readImageArrayBuffer);
const niftiReader = vtkITKImageReader.newInstance();
const mapperNifti = vtkImageMapper.newInstance();
const actorNifti = vtkImageSlice.newInstance();

niftiReader.parseAsArrayBuffer(res);
const source = niftiReader.getOutputData();
renderer.addActor(actorNifti);
actorNifti.setMapper(mapperNifti);
mapperNifti.setInputData(source);

renderWindow.render();

This results in a blank black window being rendered, while source is undefined.

Based on the working demo above, I have also attempted the following assuming that .parseAsArrayBuffer() returns a Promise:

vtkITKImageReader.setReadImageArrayBufferFromITK(readImageArrayBuffer);
const niftiReader = vtkITKImageReader.newInstance();
const mapperNifti = vtkImageMapper.newInstance();
const actorNifti = vtkImageSlice.newInstance();

niftiReader.setFileName("image.nii");
niftiReader.parseAsArrayBuffer(res).then(() => {
  const source = niftiReader.getOutputData();
  renderer.addActor(actorNifti);
  actorNifti.setMapper(mapperNifti);
  mapperNifti.setInputData(source);

  renderWindow.render();
});

This does not appear to ever go into the Promise callback, so I suspect that .parseAsArrayBuffer() no longer returns a promise…

So far, no luck! Can anyone point me in the right direction? Thanks!

Should be:

Just a guess?

Hi Donny,

Thanks for the response! I gave that a shot, but niftiReader is an instance of vtkITKImageReader and the setReadImageArrayBufferFromITK method is not defined for it. The vtkITKImageReader class has that method defined for the class overall, but the actual instances themselves have methods like .getOutputData()…which seems to stuck as undefined for me right now.

Thanks for taking a crack at it…anything else is greatly appreciated!

I’m updating this with the (unrelated) cause of this problem. I traced the call to the webWorkerPromise called here that was never being returned. That led me to look into the itk.js setup more carefully and I realized that I had not configured webpack correctly per instructions here so that the WebWorkers were available. However, since my app is based on Create React App, the webpack configs were not immediately changeable and I ended up using craco-itk so that I could use the WebWorkers required for reading in the .nii format files. I will also mention that there is Create ITK App for bootstraping a React App, though it does use CRACO, so it’s not “100% CRA” but also not ejected.

All in all, the vtkITKImageReader was a bit of a red-herring but hopefully this can help someone in the future.