Skip to main content

Loading images

NiiVue loads volumes with loadVolumes. Pass it an array of options objects, one per volume. The only required field is url.

await nv.loadVolumes([{ url: '/volumes/mni152.nii.gz' }])

loadVolumes replaces whatever was loaded before. The old volumes stay on screen until the new ones are ready, so switching images does not flash a blank canvas. Pick another image below to see it:

import NiiVue, { SLICE_TYPE } from '@niivue/niivue'

const demo = async (canvas, { ui, asset }) => {
const nv = new NiiVue({
backgroundColor: [0.2, 0.2, 0.2, 1],
sliceType: SLICE_TYPE.MULTIPLANAR,
})
await nv.attachToCanvas(canvas)
await nv.loadVolumes([{ url: asset('volumes/mni152.nii.gz') }])

const show = ui.status()
nv.addEventListener('locationChange', (e) => show(e.detail.string))

// loadVolumes replaces every loaded volume with the new list
ui.select(
'Volume',
[
['mni152 (NIfTI)', 'volumes/mni152.nii.gz'],
['visiblehuman (NIfTI)', 'volumes/visiblehuman.nii.gz'],
['wm (MGZ)', 'volumes/wm.mgz'],
],
'volumes/mni152.nii.gz',
async (path) => {
await nv.loadVolumes([{ url: asset(path) }])
},
)
return nv
}

export default demo

Volume options​

Each entry can set its display options at load time. These are the same keys that setVolume takes later, so you load and adjust with one vocabulary:

OptionWhat it does
urlA URL string or a File
nameDisplay name (defaults to the file name)
colormapColormap name, 'Gray' by default. See Colormaps
calMin, calMaxThe intensity window mapped onto the colormap
opacity0 to 1
visibleHide a volume without changing its opacity
isColorbarVisibleWhether this volume gets a colorbar
urlImageDataThe data file for formats with a separate header, such as AFNI .HEAD/.BRIK
limitFrames4DLoad only the first N frames of a 4D series

Several volumes​

The first volume in the list is the background, and it sets the space the scene is drawn in. Every later volume is an overlay: it is resampled onto the background grid and drawn on top of it.

import NiiVue, { SLICE_TYPE } from '@niivue/niivue'

const demo = async (canvas, { ui, asset }) => {
const nv = new NiiVue({
isColorbarVisible: true,
sliceType: SLICE_TYPE.MULTIPLANAR,
})
await nv.attachToCanvas(canvas)
// The first volume is the background; later ones are drawn on top of it
await nv.loadVolumes([
{
url: asset('volumes/mni152.nii.gz'),
calMin: 30,
calMax: 80,
isColorbarVisible: false,
},
{
url: asset('volumes/spmMotor.nii.gz'),
name: 'motor',
colormap: 'warm',
calMin: 3,
calMax: 6,
opacity: 0.8,
},
])

ui.slider(
'Opacity',
0,
1,
0.8,
async (v) => {
await nv.setVolume(1, { opacity: v })
},
0.05,
)
ui.checkbox('Visible', true, async (on) => {
await nv.setVolume(1, { visible: on })
})
return nv
}

export default demo

To append one volume without replacing the rest, use addVolume:

await nv.addVolume({ url: '/volumes/spmMotor.nii.gz', colormap: 'warm' })

Overlays and thresholds covers statistical maps in depth.

Meshes​

Meshes load the same way, with loadMeshes, and can share the scene with volumes:

await nv.loadMeshes([
{ url: '/meshes/BrainMesh_ICBM152.lh.mz3', color: [1, 0.8, 0.6, 1] },
])

Like loadVolumes, it replaces the meshes already loaded; addMesh appends one. See Meshes and layers for layers and shaders.

Local files and drag and drop​

Any url can be a File instead of a string. That is how you load from an <input type="file">:

input.onchange = async () => {
const file = input.files?.[0]
if (file) await nv.loadVolumes([{ url: file }])
}

If you do not know whether a file is a volume, a mesh or a signal, call nv.loadImage(file). It picks the loader from the file extension.

Drag and drop is on by default. Drop a file on the canvas and NiiVue loads it with loadImage, replacing what was shown. A dropped .nvd document goes to loadDocument, and a .json sidecar dropped together with its data file is paired with it. To turn it off:

nv.isDragDropEnabled = false

Supported formats​

Volumes: NIfTI (.nii, .nii.gz), NRRD, MRtrix MIF, AFNI HEAD/BRIK, MGH/MGZ, ITK MHD/MHA, ECAT7, DSI Studio FIB/SRC, BMP, V16, VMR, NPY/NPZ, TIFF (including OME-TIFF and ImageJ stacks), the Allen JSON+PNG atlas, and OME-Zarr.

Meshes: GIfTI, FreeSurfer, PLY, STL, OBJ, VTK, MZ3, OFF, GEO/BYU, BrainSuite DFS, ICO/TRI, BrainNet NV, BrainVoyager SRF, X3D, ASC, WRL and IWM. Tractography: TCK, TRK, TRX, TT, TSF and VTK lines.

DICOM is not built in. Convert it in the browser with the @niivue/nv-ext-dcm2niix extension (see Extensions). The MINC and VOX loader plugins from NiiVue 0.x have not been ported.

Large data​

limitFrames4D opens a long 4D series partially: NiiVue reads the header and the first frames only. The Timeseries example uses it.

OME-Zarr stores load one pyramid level at a time. loadOmeZarrVolumes returns ordinary volume options for loadVolumes:

import { loadOmeZarrVolumes } from '@niivue/niivue'

const volumes = await loadOmeZarrVolumes(storeUrl, { level: 2 })
await nv.loadVolumes(volumes)

Stores too large to load whole stream brick by brick through nv.loadChunkedVolume, with finer levels near the crosshair. These gallery pages show the streaming paths: