How to read nifti nii.gz file using VTK.js?

I’m attempting to read a .nii.gz file from the Electron backend as a buffer and parse it on the Vue frontend. Based on some older posts I found, I tried the following code:

const niftiReader = vtkITKImageReader.newInstance()
niftiReader.setFileName('image.nii.gz')
await niftiReader.parseAsArrayBuffer(arrayBuffer)
const data = niftiReader.getOutputData(0)

However, this resulted in an error related to workers:

I’m wondering if I’ve missed any worker-related settings. Any assistance would be greatly appreciated. Thank you in advance for your help.

I’m also wondering if there’s a good example of code for reading DICOM series or .nii.gz files. If anyone knows, I’d appreciate you sharing it.

What is your setup like? Is this a vite dev server accessed through an electron interface? The error you’re getting is due to CSP errors. Either the server is sending a Content-Security-Policy header or the HTML contains CSP-related meta tags.

1 Like

Yes. I’m using a Vite dev server through an Electron interface. The Content Security Policy (CSP) is set up in both the index.html file and the electron.vite.config.ts file.

// index.html

    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'self' blob:; worker-src blob:; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:"
    />

// electron.vite.config.ts

    server: {
      headers: {
        'Content-Security-Policy':
          "default-src 'self'; script-src 'self' blob:; worker-src blob:; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:"
      }
    }

I’ve confirmed that the arrayBuffer is successfully passed from the backend to the frontend through the Electron interface. Here’s the code that handles the file reading and processing:

// VtkRenderer.vue

      window.electronAPI.readFile().then(async (arrayBuffer) => {
        console.log(arrayBuffer)
        const niftiReader = vtkITKImageReader.newInstance()
        niftiReader.setFileName('1.image.nii.gz')
        niftiReader
          .parseAsArrayBuffer(arrayBuffer)
          .then(() => {
            const data = niftiReader.getOutputData(0)
            const dataRange = data.getPointData().getScalars().getRange()
            const extent = data.getExtent()

            this.setupImageMappers(data)
            this.updateColorRange(dataRange)
            this.updateExtents(extent)

            this.renderer.resetCamera()
            this.renderer.resetCameraClippingRange()
            this.renderWindow.render()
          })
          .catch((error) => {
            console.log('error:', error)
          })
      })
    },