UNPKG

@niivue/niivue

Version:

minimal webgl2 nifti image viewer

1,422 lines (1,409 loc) 124 kB
import { mat4, vec3, vec4, vec2 } from 'gl-matrix'; import { NIFTI1, NIFTI2 } from 'nifti-reader-js'; type ColorMap = { R: number[]; G: number[]; B: number[]; A: number[]; I: number[]; min?: number; max?: number; labels?: string[]; }; type LUT = { lut: Uint8ClampedArray; min?: number; max?: number; labels?: string[]; }; declare class ColorTables { gamma: number; version: number; cluts: Record<string, ColorMap>; /** * Sets cluts to alphabetically sorted cmaps */ constructor(); addColormap(key: string, cmap: ColorMap): void; colormaps(): Array<keyof typeof this.cluts>; colorMaps(): Array<keyof typeof this.cluts>; colormapFromKey(name: string): ColorMap; colormap(key?: string, isInvert?: boolean): Uint8ClampedArray; makeLabelLut(cm: ColorMap, alphaFill?: number): LUT; makeLabelLutFromUrl(name: string): Promise<LUT>; makeDrawLut(name: string | ColorMap): LUT; makeLut(Rsi: number[], Gsi: number[], Bsi: number[], Asi: number[], Isi: number[], isInvert: boolean): Uint8ClampedArray; } declare const cmapper: ColorTables; declare class Shader { program: WebGLProgram; uniforms: Record<string, WebGLUniformLocation | null>; isMatcap?: boolean; constructor(gl: WebGL2RenderingContext, vertexSrc: string, fragmentSrc: string); use(gl: WebGL2RenderingContext): void; } type Geometry = { vertexBuffer: WebGLBuffer; indexBuffer: WebGLBuffer; indexCount: number; vao: WebGLVertexArrayObject | null; }; /** * Object rendered with WebGL **/ declare class NiivueObject3D { static BLEND: number; static CULL_FACE: number; static CULL_FRONT: number; static CULL_BACK: number; static ENABLE_DEPTH_TEST: number; sphereIdx: number[]; sphereVtx: number[]; renderShaders: number[]; isVisible: boolean; isPickable: boolean; vertexBuffer: WebGLVertexArrayObject; indexCount: number; indexBuffer: WebGLVertexArrayObject | null; vao: WebGLVertexArrayObject | null; mode: number; glFlags: number; id: number; colorId: [number, number, number, number]; modelMatrix: mat4; scale: number[]; position: number[]; rotation: number[]; rotationRadians: number; extentsMin: number[]; extentsMax: number[]; furthestVertexFromOrigin?: number; originNegate?: vec3; fieldOfViewDeObliqueMM?: vec3; mm?: vec4; constructor(id: number, vertexBuffer: WebGLBuffer, mode: number, indexCount: number, indexBuffer?: WebGLVertexArrayObject | null, vao?: WebGLVertexArrayObject | null); static generateCrosshairs: (gl: WebGL2RenderingContext, id: number, xyzMM: vec4, xyzMin: vec3, xyzMax: vec3, radius: number, sides?: number, gap?: number) => NiivueObject3D; static generateCrosshairsGeometry: (gl: WebGL2RenderingContext, xyzMM: vec4, xyzMin: vec3, xyzMax: vec3, radius: number, sides?: number, gap?: number) => Geometry; static getFirstPerpVector: (v1: vec3) => vec3; static subdivide: (verts: number[], faces: number[]) => void; static weldVertices: (verts: number[], faces: number[]) => number[]; static makeSphere: (vertices: number[], indices: number[], radius: number, origin?: vec3 | vec4) => void; static makeCylinder: (vertices: number[], indices: number[], start: vec3, dest: vec3, radius: number, sides?: number, endcaps?: boolean) => void; static makeColoredCylinder: (vertices: number[], indices: number[], colors: number[], start: vec3, dest: vec3, radius: number, rgba255?: number[], sides?: number, endcaps?: boolean) => void; static makeColoredSphere: (vertices: number[], indices: number[], colors: number[], radius: number, origin?: vec3 | vec4, rgba255?: number[]) => void; } declare enum LabelTextAlignment { LEFT = "left", RIGHT = "right", CENTER = "center" } declare enum LabelLineTerminator { NONE = "none", CIRCLE = "circle", RING = "ring" } declare enum LabelAnchorPoint { NONE = 0, TOPLEFT = 9, TOPCENTER = 10, TOPRIGHT = 12, MIDDLELEFT = 17, MIDDLECENTER = 18, MIDDLERIGHT = 20, BOTTOMLEFT = 33, BOTTOMCENTER = 34, BOTTOMRIGHT = 36 } /** * Class representing label style. * @ignore */ declare class NVLabel3DStyle { textColor: number[]; textScale: number; textAlignment?: LabelTextAlignment; lineWidth: number; lineColor: number[]; lineTerminator: LabelLineTerminator; bulletScale?: number; bulletColor?: number[]; backgroundColor?: number[]; /** * @param textColor - Color of text * @param textScale - Text Size (0.0..1.0) * @param lineWidth - Line width * @param lineColor - Line color * @param bulletScale - Bullet size respective of text * @param bulletColor - Bullet color * @param backgroundColor - Background color of label */ constructor(textColor?: number[], textScale?: number, textAlignment?: LabelTextAlignment, lineWidth?: number, lineColor?: number[], lineTerminator?: LabelLineTerminator, bulletScale?: number, bulletColor?: number[], backgroundColor?: number[]); } /** * Label class * @ignore */ declare class NVLabel3D { text: string; style: NVLabel3DStyle; points?: number[] | number[][]; anchor: LabelAnchorPoint; onClick?: (label: NVLabel3D) => void; /** * @param text - The text of the label * @param style - The style of the label * @param points - An array of points label for label lines */ constructor(text: string, style: NVLabel3DStyle, points?: number[] | number[][], anchor?: LabelAnchorPoint, onClick?: (label: NVLabel3D) => void); } /** * Enum for NIfTI datatype codes * // https://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h */ declare enum NiiDataType { DT_NONE = 0, DT_BINARY = 1, DT_UINT8 = 2, DT_INT16 = 4, DT_INT32 = 8, DT_FLOAT32 = 16, DT_COMPLEX64 = 32, DT_FLOAT64 = 64, DT_RGB24 = 128, DT_INT8 = 256, DT_UINT16 = 512, DT_UINT32 = 768, DT_INT64 = 1024, DT_UINT64 = 1280, DT_FLOAT128 = 1536, DT_COMPLEX128 = 1792, DT_COMPLEX256 = 2048, DT_RGBA32 = 2304 } /** * Enum for supported image types (e.g. NII, NRRD, DICOM) */ declare enum ImageType { UNKNOWN = 0, NII = 1, DCM = 2, DCM_MANIFEST = 3, MIH = 4, MIF = 5, NHDR = 6, NRRD = 7, MHD = 8, MHA = 9, MGH = 10, MGZ = 11, V = 12, V16 = 13, VMR = 14, HEAD = 15, DCM_FOLDER = 16, SRC = 17, FIB = 18, BMP = 19, ZARR = 20, NPY = 21, NPZ = 22 } type ImageFromUrlOptions = { url: string; urlImageData?: string; headers?: Record<string, string>; name?: string; colorMap?: string; colormap?: string; opacity?: number; cal_min?: number; cal_max?: number; trustCalMinMax?: boolean; percentileFrac?: number; useQFormNotSForm?: boolean; alphaThreshold?: boolean; colormapNegative?: string; colorMapNegative?: string; cal_minNeg?: number; cal_maxNeg?: number; colorbarVisible?: boolean; ignoreZeroVoxels?: boolean; imageType?: ImageType; frame4D?: number; colormapLabel?: LUT | null; pairedImgData?: null; limitFrames4D?: number; isManifest?: boolean; urlImgData?: string; buffer?: ArrayBuffer; }; type ImageFromFileOptions = { file: File | File[]; name?: string; colormap?: string; opacity?: number; urlImgData?: File | null | FileSystemEntry; cal_min?: number; cal_max?: number; trustCalMinMax?: boolean; percentileFrac?: number; ignoreZeroVoxels?: boolean; useQFormNotSForm?: boolean; colormapNegative?: string; imageType?: ImageType; frame4D?: number; limitFrames4D?: number; }; type ImageFromBase64 = { base64: string; name?: string; colormap?: string; opacity?: number; cal_min?: number; cal_max?: number; trustCalMinMax?: boolean; percentileFrac?: number; ignoreZeroVoxels?: boolean; useQFormNotSForm?: boolean; colormapNegative?: string; frame4D?: number; imageType?: ImageType; cal_minNeg?: number; cal_maxNeg?: number; colorbarVisible?: boolean; colormapLabel?: LUT | null; }; type ImageMetadata = { id: string; datatypeCode: number; nx: number; ny: number; nz: number; nt: number; dx: number; dy: number; dz: number; dt: number; bpv: number; }; declare const NVImageFromUrlOptions: (url: string, urlImageData?: string, name?: string, colormap?: string, opacity?: number, cal_min?: number, cal_max?: number, trustCalMinMax?: boolean, percentileFrac?: number, ignoreZeroVoxels?: boolean, useQFormNotSForm?: boolean, colormapNegative?: string, frame4D?: number, imageType?: ImageType, cal_minNeg?: number, cal_maxNeg?: number, colorbarVisible?: boolean, alphaThreshold?: boolean, colormapLabel?: any) => ImageFromUrlOptions; type TypedVoxelArray = Float32Array | Uint8Array | Int16Array | Float64Array | Uint16Array; /** * a NVImage encapsulates some images data and provides methods to query and operate on images */ declare class NVImage { name: string; id: string; url?: string; headers?: Record<string, string>; _colormap: string; _opacity: number; percentileFrac: number; ignoreZeroVoxels: boolean; trustCalMinMax: boolean; colormapNegative: string; colormapLabel: LUT | null; colormapInvert?: boolean; nFrame4D?: number; frame4D: number; nTotalFrame4D?: number; cal_minNeg: number; cal_maxNeg: number; colorbarVisible: boolean; modulationImage: number | null; modulateAlpha: number; series: any; nVox3D?: number; oblique_angle?: number; maxShearDeg?: number; useQFormNotSForm: boolean; colormapType?: number; pixDims?: number[]; matRAS?: mat4; pixDimsRAS?: number[]; obliqueRAS?: mat4; dimsRAS?: number[]; permRAS?: number[]; img2RASstep?: number[]; img2RASstart?: number[]; toRAS?: mat4; toRASvox?: mat4; frac2mm?: mat4; frac2mmOrtho?: mat4; extentsMinOrtho?: number[]; extentsMaxOrtho?: number[]; mm2ortho?: mat4; hdr: NIFTI1 | NIFTI2 | null; imageType?: ImageType; img?: TypedVoxelArray; imaginary?: Float32Array; v1?: Float32Array; fileObject?: File | File[]; dims?: number[]; onColormapChange: (img: NVImage) => void; onOpacityChange: (img: NVImage) => void; mm000?: vec3; mm100?: vec3; mm010?: vec3; mm001?: vec3; cal_min?: number; cal_max?: number; robust_min?: number; robust_max?: number; global_min?: number; global_max?: number; urlImgData?: string; isManifest?: boolean; limitFrames4D?: number; /** * * @param dataBuffer - an array buffer of image data to load (there are also methods that abstract this more. See loadFromUrl, and loadFromFile) * @param name - a name for this image. Default is an empty string * @param colormap - a color map to use. default is gray * @param opacity - the opacity for this image. default is 1 * @param pairedImgData - Allows loading formats where header and image are separate files (e.g. nifti.hdr, nifti.img) * @param cal_min - minimum intensity for color brightness/contrast * @param cal_max - maximum intensity for color brightness/contrast * @param trustCalMinMax - whether or not to trust cal_min and cal_max from the nifti header (trusting results in faster loading) * @param percentileFrac - the percentile to use for setting the robust range of the display values (smart intensity setting for images with large ranges) * @param ignoreZeroVoxels - whether or not to ignore zero voxels in setting the robust range of display values * @param useQFormNotSForm - give precedence to QForm (Quaternion) or SForm (Matrix) * @param colormapNegative - a color map to use for symmetrical negative intensities * @param frame4D - volume displayed, 0 indexed, must be less than nFrame4D * * FIXME the following params are documented but not included in the actual constructor * @param onColormapChange - callback for color map change * @param onOpacityChange -callback for color map change * * TODO the following parameters were not documented * @param imageType - TODO * @param cal_minNeg - TODO * @param cal_maxNeg - TODO * @param colorbarVisible - TODO * @param colormapLabel - TODO */ constructor(dataBuffer?: ArrayBuffer | ArrayBuffer[] | ArrayBufferLike | null, name?: string, colormap?: string, opacity?: number, pairedImgData?: ArrayBuffer | null, cal_min?: number, cal_max?: number, trustCalMinMax?: boolean, percentileFrac?: number, ignoreZeroVoxels?: boolean, useQFormNotSForm?: boolean, colormapNegative?: string, frame4D?: number, imageType?: ImageType, cal_minNeg?: number, cal_maxNeg?: number, colorbarVisible?: boolean, colormapLabel?: LUT | null, colormapType?: number); init(dataBuffer?: ArrayBuffer | ArrayBuffer[] | ArrayBufferLike | null, name?: string, colormap?: string, opacity?: number, _pairedImgData?: ArrayBuffer | null, cal_min?: number, cal_max?: number, trustCalMinMax?: boolean, percentileFrac?: number, ignoreZeroVoxels?: boolean, useQFormNotSForm?: boolean, colormapNegative?: string, frame4D?: number, imageType?: ImageType, cal_minNeg?: number, cal_maxNeg?: number, colorbarVisible?: boolean, colormapLabel?: LUT | null, colormapType?: number, imgRaw?: ArrayBuffer | ArrayBufferLike | null): void; static new(dataBuffer?: ArrayBuffer | ArrayBuffer[] | ArrayBufferLike | null, name?: string, colormap?: string, opacity?: number, pairedImgData?: ArrayBuffer | null, cal_min?: number, cal_max?: number, trustCalMinMax?: boolean, percentileFrac?: number, ignoreZeroVoxels?: boolean, useQFormNotSForm?: boolean, colormapNegative?: string, frame4D?: number, imageType?: ImageType, cal_minNeg?: number, cal_maxNeg?: number, colorbarVisible?: boolean, colormapLabel?: LUT | null, colormapType?: number): Promise<NVImage>; computeObliqueAngle(mtx44: mat4): number; float32V1asRGBA(inImg: Float32Array): Uint8Array; loadImgV1(isFlipX?: boolean, isFlipY?: boolean, isFlipZ?: boolean): boolean; calculateOblique(): void; THD_daxes_to_NIFTI(xyzDelta: number[], xyzOrigin: number[], orientSpecific: number[]): void; SetPixDimFromSForm(): void; readECAT(buffer: ArrayBuffer): ArrayBuffer; readV16(buffer: ArrayBuffer): ArrayBuffer; readNPY(buffer: ArrayBuffer): Promise<ArrayBuffer>; readNPZ(buffer: ArrayBuffer): Promise<ArrayBuffer>; imageDataFromArrayBuffer(buffer: ArrayBuffer): Promise<ImageData>; readBMP(buffer: ArrayBuffer): Promise<ArrayBuffer>; readVMR(buffer: ArrayBuffer): ArrayBuffer; readFIB(buffer: ArrayBuffer): Promise<[ArrayBuffer, Float32Array]>; readSRC(buffer: ArrayBuffer): Promise<ArrayBuffer>; readHEAD(dataBuffer: ArrayBuffer, pairedImgData: ArrayBuffer | null): Promise<ArrayBuffer>; readMHA(buffer: ArrayBuffer, pairedImgData: ArrayBuffer | null): Promise<ArrayBuffer>; readMIF(buffer: ArrayBuffer, pairedImgData: ArrayBuffer | null): Promise<ArrayBuffer>; calculateRAS(): void; hdr2RAS(nVolumes?: number): Promise<NIFTI1 | NIFTI2>; img2RAS(nVolume?: number): TypedVoxelArray; vox2mm(XYZ: number[], mtx: mat4): vec3; mm2vox(mm: number[], frac?: boolean): Float32Array | vec3; arrayEquals(a: unknown[], b: unknown[]): boolean; setColormap(cm: string): void; setColormapLabel(cm: ColorMap): void; setColormapLabelFromUrl(url: string): Promise<void>; get colormap(): string; get colorMap(): string; set colormap(cm: string); set colorMap(cm: string); get opacity(): number; set opacity(opacity: number); /** * set contrast/brightness to robust range (2%..98%) * @param vol - volume for estimate (use -1 to use estimate on all loaded volumes; use INFINITY for current volume) * @param isBorder - if true (default) only center of volume used for estimate * @sets volume brightness and returns array [pct2, pct98, mnScale, mxScale] * @see {@link https://niivue.github.io/niivue/features/timeseries2.html | live demo usage} */ calMinMax(vol?: number, isBorder?: boolean): number[]; intensityRaw2Scaled(raw: number): number; intensityScaled2Raw(scaled: number): number; /** * Converts NVImage to NIfTI compliant byte array, potentially compressed. * Delegates to ImageWriter.saveToUint8Array. * @param fnm - Filename (determines if compression is needed via .gz suffix) * @param drawing8 - Optional Uint8Array drawing overlay * @returns Promise<Uint8Array> */ saveToUint8Array(fnm: string, drawing8?: Uint8Array | null): Promise<Uint8Array>; /** * save image as NIfTI volume and trigger download. * Delegates to ImageWriter.saveToDisk. * @param fnm - Filename for download. If empty, returns data without download. * @param drawing8 - Optional Uint8Array drawing overlay * @returns Promise<Uint8Array> */ saveToDisk(fnm?: string, drawing8?: Uint8Array | null): Promise<Uint8Array>; static fetchDicomData(url: string, headers?: Record<string, string>): Promise<Array<{ name: string; data: ArrayBuffer; }>>; static readFirstDecompressedBytes(stream: ReadableStream<Uint8Array>, minBytes: number): Promise<Uint8Array>; static extractFilenameFromUrl(url: string): string | null; static loadInitialVolumesGz(url?: string, headers?: {}, limitFrames4D?: number): Promise<ArrayBuffer | null>; static loadInitialVolumes(url?: string, headers?: {}, limitFrames4D?: number): Promise<ArrayBuffer | null>; /** * factory function to load and return a new NVImage instance from a given URL * @returns NVImage instance */ static loadFromUrl({ url, urlImgData, headers, name, colormap, opacity, cal_min, cal_max, trustCalMinMax, percentileFrac, ignoreZeroVoxels, useQFormNotSForm, colormapNegative, frame4D, isManifest, limitFrames4D, imageType, colorbarVisible, buffer }?: Partial<Omit<ImageFromUrlOptions, 'url'>> & { url?: string | Uint8Array | ArrayBuffer; }): Promise<NVImage>; static readFileAsync(file: File, bytesToLoad?: number): Promise<ArrayBuffer>; /** * factory function to load and return a new NVImage instance from a file in the browser */ static loadFromFile({ file, // file can be an array of file objects or a single file object name, colormap, opacity, urlImgData, cal_min, cal_max, trustCalMinMax, percentileFrac, ignoreZeroVoxels, useQFormNotSForm, colormapNegative, frame4D, limitFrames4D, imageType }: ImageFromFileOptions): Promise<NVImage>; /** * Creates a Uint8Array representing a NIFTI file (header + optional image data). * Delegates to ImageWriter.createNiftiArray. */ static createNiftiArray(dims?: number[], pixDims?: number[], affine?: number[], datatypeCode?: NiiDataType, img?: TypedVoxelArray | Uint8Array): Uint8Array; /** * Creates a NIFTI1 header object with basic properties. * Delegates to ImageWriter.createNiftiHeader. */ static createNiftiHeader(dims?: number[], pixDims?: number[], affine?: number[], datatypeCode?: NiiDataType): NIFTI1; /** * read a 3D slab of voxels from a volume * @param voxStart - first row, column and slice (RAS order) for selection * @param voxEnd - final row, column and slice (RAS order) for selection * @param dataType - array data type. Options: 'same' (default), 'uint8', 'float32', 'scaled', 'normalized', 'windowed' * @returns the an array where ret[0] is the voxel values and ret[1] is dimension of selection * @see {@link https://niivue.github.io/niivue/features/slab_selection.html | live demo usage} */ /** * read a 3D slab of voxels from a volume, specified in RAS coordinates. * Delegates to VolumeUtils.getVolumeData. * @param voxStart - first row, column and slice (RAS order) for selection * @param voxEnd - final row, column and slice (RAS order) for selection * @param dataType - array data type. Options: 'same' (default), 'uint8', 'float32', 'scaled', 'normalized', 'windowed' * @returns the an array where ret[0] is the voxel values and ret[1] is dimension of selection */ getVolumeData(voxStart?: number[], voxEnd?: number[], dataType?: string): [TypedVoxelArray, number[]]; /** * write a 3D slab of voxels from a volume * @param voxStart - first row, column and slice (RAS order) for selection * @param voxEnd - final row, column and slice (RAS order) for selection * @param img - array of voxel values to insert (RAS order) * @see {@link https://niivue.github.io/niivue/features/slab_selection.html | live demo usage} */ /** * write a 3D slab of voxels from a volume, specified in RAS coordinates. * Delegates to VolumeUtils.setVolumeData. * Input slabData is assumed to be in the correct raw data type for the target image. * @param voxStart - first row, column and slice (RAS order) for selection * @param voxEnd - final row, column and slice (RAS order) for selection * @param img - array of voxel values to insert (RAS order, raw data type) */ setVolumeData(voxStart?: number[], voxEnd?: number[], img?: TypedVoxelArray): void; /** * factory function to load and return a new NVImage instance from a base64 encoded string * * @returns NVImage instance * @example * myImage = NVImage.loadFromBase64('SomeBase64String') */ static loadFromBase64({ base64, name, colormap, opacity, cal_min, cal_max, trustCalMinMax, percentileFrac, ignoreZeroVoxels, useQFormNotSForm, colormapNegative, frame4D, imageType, cal_minNeg, cal_maxNeg, colorbarVisible, colormapLabel }: ImageFromBase64): Promise<NVImage>; /** * make a clone of a NVImage instance and return a new NVImage * @returns NVImage instance * @example * myImage = NVImage.loadFromFile(SomeFileObject) // files can be from dialogs or drag and drop * clonedImage = myImage.clone() */ clone(): NVImage; /** * fill a NVImage instance with zeros for the image data * @example * myImage = NVImage.loadFromFile(SomeFileObject) // files can be from dialogs or drag and drop * clonedImageWithZeros = myImage.clone().zeroImage() */ zeroImage(): void; /** * get nifti specific metadata about the image */ getImageMetadata(): ImageMetadata; /** * a factory function to make a zero filled image given a NVImage as a reference * @param nvImage - an existing NVImage as a reference * @param dataType - the output data type. Options: 'same', 'uint8' * @returns new NVImage filled with zeros for the image data * @example * myImage = NVImage.loadFromFile(SomeFileObject) // files can be from dialogs or drag and drop * newZeroImage = NVImage.zerosLike(myImage) */ static zerosLike(nvImage: NVImage, dataType?: string): NVImage; /** * Returns voxel intensity at specific native coordinates. * Delegates to VolumeUtils.getValue. * @param x - Native X coordinate (0-indexed) * @param y - Native Y coordinate (0-indexed) * @param z - Native Z coordinate (0-indexed) * @param frame4D - 4D frame index (0-indexed) * @param isReadImaginary - Flag to read from imaginary data array * @returns Scaled voxel intensity */ getValue(x: number, y: number, z: number, frame4D?: number, isReadImaginary?: boolean): number; /** * Update options for image */ applyOptionsUpdate(options: ImageFromUrlOptions): void; getImageOptions(): ImageFromUrlOptions; /** * Converts NVImage to NIfTI compliant byte array. * Handles potential re-orientation of drawing data. * Delegates to ImageWriter.toUint8Array. * @param drawingBytes - Optional Uint8Array drawing overlay * @returns Uint8Array */ toUint8Array(drawingBytes?: Uint8Array | null): Uint8Array; convertVox2Frac(vox: vec3): vec3; convertFrac2Vox(frac: vec3): vec3; convertFrac2MM(frac: vec3, isForceSliceMM?: boolean): vec4; convertMM2Frac(mm: vec3 | vec4, isForceSliceMM?: boolean): vec3; } type FreeSurferConnectome = { data_type: string; points: Array<{ comments?: Array<{ text: string; }>; coordinates: { x: number; y: number; z: number; }; }>; }; /** * Represents a connectome */ declare class NVConnectome extends NVMesh { gl: WebGL2RenderingContext; nodesChanged: EventTarget; constructor(gl: WebGL2RenderingContext, connectome: LegacyConnectome); static convertLegacyConnectome(json: LegacyConnectome): Connectome; static convertFreeSurferConnectome(json: FreeSurferConnectome, colormap?: string): Connectome; updateLabels(): void; addConnectomeNode(node: NVConnectomeNode): void; deleteConnectomeNode(node: NVConnectomeNode): void; updateConnectomeNodeByIndex(index: number, updatedNode: NVConnectomeNode): void; updateConnectomeNodeByPoint(point: [number, number, number], updatedNode: NVConnectomeNode): void; addConnectomeEdge(first: number, second: number, colorValue: number): NVConnectomeEdge; deleteConnectomeEdge(first: number, second: number): NVConnectomeEdge; findClosestConnectomeNode(point: number[], distance: number): NVConnectomeNode | null; updateConnectome(gl: WebGL2RenderingContext): void; updateMesh(gl: WebGL2RenderingContext): void; json(): Connectome; /** * Factory method to create connectome from options */ static loadConnectomeFromUrl(gl: WebGL2RenderingContext, url: string): Promise<NVConnectome>; } /** * Slice Type * @ignore */ declare enum SLICE_TYPE { AXIAL = 0, CORONAL = 1, SAGITTAL = 2, MULTIPLANAR = 3, RENDER = 4 } declare enum SHOW_RENDER { NEVER = 0, ALWAYS = 1, AUTO = 2 } /** * Multi-planar layout * @ignore */ declare enum MULTIPLANAR_TYPE { AUTO = 0, COLUMN = 1, GRID = 2, ROW = 3 } /** * Drag mode * @ignore */ declare enum DRAG_MODE { none = 0, contrast = 1, measurement = 2, pan = 3, slicer3D = 4, callbackOnly = 5, roiSelection = 6 } declare enum DRAG_MODE_SECONDARY { none = 0, contrast = 1, measurement = 2, pan = 3, slicer3D = 4, callbackOnly = 5, roiSelection = 6 } declare enum DRAG_MODE_PRIMARY { crosshair = 0, windowing = 1 } declare enum COLORMAP_TYPE { MIN_TO_MAX = 0, ZERO_TO_MAX_TRANSPARENT_BELOW_MIN = 1, ZERO_TO_MAX_TRANSLUCENT_BELOW_MIN = 2 } /** * NVConfigOptions */ type NVConfigOptions = { textHeight: number; colorbarHeight: number; crosshairWidth: number; crosshairWidthUnit: 'voxels' | 'mm' | 'percent'; crosshairGap: number; rulerWidth: number; show3Dcrosshair: boolean; backColor: number[]; crosshairColor: number[]; fontColor: Float32List; selectionBoxColor: number[]; clipPlaneColor: number[]; clipThick: number; clipVolumeLow: number[]; clipVolumeHigh: number[]; rulerColor: number[]; colorbarMargin: number; trustCalMinMax: boolean; clipPlaneHotKey: string; viewModeHotKey: string; doubleTouchTimeout: number; longTouchTimeout: number; keyDebounceTime: number; isNearestInterpolation: boolean; atlasOutline: number; isRuler: boolean; isColorbar: boolean; isOrientCube: boolean; tileMargin: number; multiplanarPadPixels: number; multiplanarForceRender: boolean; multiplanarEqualSize: boolean; multiplanarShowRender: SHOW_RENDER; isRadiologicalConvention: boolean; meshThicknessOn2D: number | string; dragMode: DRAG_MODE | DRAG_MODE_SECONDARY; dragModePrimary: DRAG_MODE_PRIMARY; yoke3Dto2DZoom: boolean; isDepthPickMesh: boolean; isCornerOrientationText: boolean; heroImageFraction: number; heroSliceType: SLICE_TYPE; sagittalNoseLeft: boolean; isSliceMM: boolean; isV1SliceShader: boolean; forceDevicePixelRatio: number; logLevel: 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent'; loadingText: string; isForceMouseClickToVoxelCenters: boolean; dragAndDropEnabled: boolean; drawingEnabled: boolean; penValue: number; floodFillNeighbors: number; isFilledPen: boolean; thumbnail: string; maxDrawUndoBitmaps: number; sliceType: SLICE_TYPE; isAntiAlias: boolean | null; isAdditiveBlend: boolean; isResizeCanvas: boolean; meshXRay: number; limitFrames4D: number; showLegend: boolean; legendBackgroundColor: number[]; legendTextColor: number[]; multiplanarLayout: MULTIPLANAR_TYPE; renderOverlayBlend: number; sliceMosaicString: string; centerMosaic: boolean; interactive: boolean; penSize: number; clickToSegment: boolean; clickToSegmentRadius: number; clickToSegmentBright: boolean; clickToSegmentAutoIntensity: boolean; clickToSegmentIntensityMax: number; clickToSegmentIntensityMin: number; clickToSegmentPercent: number; clickToSegmentMaxDistanceMM: number; clickToSegmentIs2D: boolean; selectionBoxLineThickness: number; selectionBoxIsOutline: boolean; scrollRequiresFocus: boolean; showMeasureUnits: boolean; measureTextJustify: 'start' | 'center' | 'end'; measureTextColor: number[]; measureLineColor: number[]; measureTextHeight: number; isAlphaClipDark: boolean; gradientOrder: number; gradientOpacity: number; invertScrollDirection: boolean; }; declare const DEFAULT_OPTIONS: NVConfigOptions; type SceneData = { gamma: number; azimuth: number; elevation: number; crosshairPos: vec3; clipPlane: number[]; clipPlaneDepthAziElev: number[]; volScaleMultiplier: number; pan2Dxyzmm: vec4; clipThick: number; clipVolumeLow: number[]; clipVolumeHigh: number[]; }; declare const INITIAL_SCENE_DATA: { gamma: number; azimuth: number; elevation: number; crosshairPos: vec3; clipPlane: number[]; clipPlaneDepthAziElev: number[]; volScaleMultiplier: number; pan2Dxyzmm: vec4; clipThick: number; clipVolumeLow: number[]; clipVolumeHigh: number[]; }; type Scene = { onAzimuthElevationChange: (azimuth: number, elevation: number) => void; onZoom3DChange: (scale: number) => void; sceneData: SceneData; renderAzimuth: number; renderElevation: number; volScaleMultiplier: number; crosshairPos: vec3; clipPlane: number[]; clipPlaneDepthAziElev: number[]; pan2Dxyzmm: vec4; _elevation?: number; _azimuth?: number; gamma?: number; }; type DocumentData = { title: string; imageOptionsArray: ImageFromUrlOptions[]; meshOptionsArray: unknown[]; opts: NVConfigOptions; previewImageDataURL: string; labels: NVLabel3D[]; encodedImageBlobs: string[]; encodedDrawingBlob: string; meshesString?: string; sceneData?: SceneData; connectomes?: string[]; customData?: string; }; type ExportDocumentData = { encodedImageBlobs: string[]; encodedDrawingBlob: string; previewImageDataURL: string; imageOptionsMap: Map<string, number>; imageOptionsArray: ImageFromUrlOptions[]; sceneData: Partial<SceneData>; opts: NVConfigOptions; meshesString: string; labels: NVLabel3D[]; connectomes: string[]; customData: string; }; /** * Creates and instance of NVDocument * @ignore */ declare class NVDocument { data: DocumentData; scene: Scene; volumes: NVImage[]; meshDataObjects?: Array<NVMesh | NVConnectome>; meshes: Array<NVMesh | NVConnectome>; drawBitmap: Uint8Array | null; imageOptionsMap: Map<any, any>; meshOptionsMap: Map<any, any>; constructor(); /** * Title of the document */ get title(): string; /** * Gets preview image blob * @returns dataURL of preview image */ get previewImageDataURL(): string; /** * Sets preview image blob * @param dataURL - encoded preview image */ set previewImageDataURL(dataURL: string); /** * @param title - title of document */ set title(title: string); get imageOptionsArray(): ImageFromUrlOptions[]; /** * Gets the base 64 encoded blobs of associated images */ get encodedImageBlobs(): string[]; /** * Gets the base 64 encoded blob of the associated drawing * TODO the return type was marked as string[] here, was that an error? */ get encodedDrawingBlob(): string; /** * Gets the options of the {@link Niivue} instance */ get opts(): NVConfigOptions; /** * Sets the options of the {@link Niivue} instance */ set opts(opts: NVConfigOptions); /** * Gets the 3D labels of the {@link Niivue} instance */ get labels(): NVLabel3D[]; /** * Sets the 3D labels of the {@link Niivue} instance */ set labels(labels: NVLabel3D[]); get customData(): string | undefined; set customData(data: string); /** * Checks if document has an image by id */ hasImage(image: NVImage): boolean; /** * Checks if document has an image by url */ hasImageFromUrl(url: string): boolean; /** * Adds an image and the options an image was created with */ addImageOptions(image: NVImage, imageOptions: ImageFromUrlOptions): void; /** * Removes image from the document as well as its options */ removeImage(image: NVImage): void; /** * Returns the options for the image if it was added by url */ getImageOptions(image: NVImage): ImageFromUrlOptions | null; /** * Converts NVDocument to JSON */ json(): ExportDocumentData; /** * Downloads a JSON file with options, scene, images, meshes and drawing of {@link Niivue} instance */ download(fileName: string, compress: boolean): Promise<void>; /** * Deserialize mesh data objects */ static deserializeMeshDataObjects(document: NVDocument): void; /** * Factory method to return an instance of NVDocument from a URL */ static loadFromUrl(url: string): Promise<NVDocument>; /** * Factory method to return an instance of NVDocument from a File object */ static loadFromFile(file: Blob): Promise<NVDocument>; /** * Factory method to return an instance of NVDocument from JSON */ static loadFromJSON(data: DocumentData): NVDocument; } type NiftiHeader = { littleEndian: boolean; dim_info: number; dims: number[]; pixDims: number[]; intent_p1: number; intent_p2: number; intent_p3: number; intent_code: number; datatypeCode: number; numBitsPerVoxel: number; slice_start: number; vox_offset: number; scl_slope: number; scl_inter: number; slice_end: number; slice_code: number; xyzt_units: number; cal_max: number; cal_min: number; slice_duration: number; toffset: number; description: string; aux_file: string; qform_code: number; sform_code: number; quatern_b: number; quatern_c: number; quatern_d: number; qoffset_x: number; qoffset_y: number; qoffset_z: number; affine: number[][]; intent_name: string; magic: string; }; type Volume = Record<string, any>; type Point = { comments: Array<{ text: string; prefilled?: string; }>; coordinates: { x: number; y: number; z: number; }; }; /** * Represents the vertices of a connectome * @ignore */ type NVConnectomeNode = { name: string; x: number; y: number; z: number; colorValue: number; sizeValue: number; label?: NVLabel3D; }; /** * Represents edges between connectome nodes * @ignore */ type NVConnectomeEdge = { first: number; second: number; colorValue: number; }; type ConnectomeOptions = { name: string; nodeColormap: string; nodeColormapNegative: string; nodeMinColor: number; nodeMaxColor: number; nodeScale: number; edgeColormap: string; edgeColormapNegative: string; edgeMin: number; edgeMax: number; edgeScale: number; legendLineThickness?: number; }; type Connectome = ConnectomeOptions & { nodes: NVConnectomeNode[]; edges: NVConnectomeEdge[]; }; type LegacyNodes = { names: string[]; prefilled: unknown[]; X: number[]; Y: number[]; Z: number[]; Color: number[]; Size: number[]; }; type LegacyConnectome = Partial<ConnectomeOptions> & { nodes: LegacyNodes; edges: number[]; }; type DragReleaseParams = { fracStart: vec3; fracEnd: vec3; voxStart: vec3; voxEnd: vec3; mmStart: vec4; mmEnd: vec4; mmLength: number; tileIdx: number; axCorSag: SLICE_TYPE; }; type NiiVueLocationValue = { id: string; mm: vec4; name: string; value: number; vox: vec3; }; type NiiVueLocation = { axCorSag: number; frac: vec3; mm: vec4; string: string; values: NiiVueLocationValue[]; vox: vec3; xy: [number, number]; }; type SyncOpts = { '3d'?: boolean; '2d'?: boolean; zoomPan?: boolean; cal_min?: boolean; cal_max?: boolean; gamma?: boolean; useSliceOffset?: boolean; sliceType?: boolean; crosshair?: boolean; clipPlane?: boolean; }; type ValuesArray = Array<{ id: string; vals: Float32Array; global_min?: number; global_max?: number; cal_min?: number; cal_max?: number; }>; type AnyNumberArray = number[] | Float64Array | Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array; type DefaultMeshType = { positions: Float32Array; indices: Uint32Array; colors?: Float32Array; }; type TRACT = { pts: Float32Array; offsetPt0: Uint32Array; dps: ValuesArray; }; type TT = { pts: Float32Array; offsetPt0: Uint32Array; }; type TRX = { pts: Float32Array; offsetPt0: Uint32Array; dpg: ValuesArray; dps: ValuesArray; dpv: ValuesArray; header: unknown; }; type TRK = { pts: Float32Array; offsetPt0: Uint32Array; dps: ValuesArray; dpv: ValuesArray; }; type TCK = { pts: Float32Array; offsetPt0: Uint32Array; }; type VTK = DefaultMeshType | { pts: Float32Array; offsetPt0: Uint32Array; }; type ANNOT = Uint32Array | { scalars: Float32Array; colormapLabel: LUT; }; type MZ3 = { positions: Float32Array | null; indices: Uint32Array | null; scalars: Float32Array; colors: Float32Array | null; } | { scalars: Float32Array; colormapLabel: LUT; } | { scalars: Float32Array; }; type GII = { scalars: Float32Array; positions?: Float32Array; indices?: Uint32Array; colormapLabel?: LUT; anatomicalStructurePrimary: string; }; type MGH = AnyNumberArray | { scalars: AnyNumberArray; colormapLabel: LUT; }; type X3D = { positions: Float32Array; indices: Uint32Array; rgba255: Uint8Array; }; /** Enum for text alignment */ declare enum MeshType { MESH = "mesh", CONNECTOME = "connectome", FIBER = "fiber" } type NVMeshLayer = { name?: string; key?: string; url?: string; headers?: Record<string, string>; opacity: number; colormap: string; colormapNegative?: string; colormapInvert?: boolean; colormapLabel?: ColorMap | LUT; useNegativeCmap?: boolean; global_min?: number; global_max?: number; cal_min: number; cal_max: number; cal_minNeg: number; cal_maxNeg: number; isAdditiveBlend?: boolean; frame4D: number; nFrame4D: number; values: AnyNumberArray; outlineBorder?: number; isTransparentBelowCalMin?: boolean; colormapType?: number; base64?: string; colorbarVisible?: boolean; }; declare const NVMeshLayerDefaults: { colormap: string; opacity: number; nFrame4D: number; frame4D: number; outlineBorder: number; cal_min: number; cal_max: number; cal_minNeg: number; cal_maxNeg: number; colormapType: COLORMAP_TYPE; values: number[]; }; declare class NVMeshFromUrlOptions { url: string; gl: WebGL2RenderingContext | null; name: string; opacity: number; rgba255: Uint8Array; visible: boolean; layers: NVMeshLayer[]; colorbarVisible: boolean; constructor(url?: string, gl?: any, name?: string, opacity?: number, rgba255?: Uint8Array, visible?: boolean, layers?: any[], colorbarVisible?: boolean); } type BaseLoadParams = { gl: WebGL2RenderingContext; name: string; opacity: number; rgba255: number[] | Uint8Array; visible: boolean; layers: NVMeshLayer[]; }; type LoadFromUrlParams = Partial<BaseLoadParams> & { url: string; headers?: Record<string, string>; buffer?: ArrayBuffer; }; type LoadFromFileParams = BaseLoadParams & { file: Blob; }; type LoadFromBase64Params = BaseLoadParams & { base64: string; }; /** * a NVMesh encapsulates some mesh data and provides methods to query and operate on meshes */ declare class NVMesh { id: string; name: string; anatomicalStructurePrimary: string; colorbarVisible: boolean; furthestVertexFromOrigin: number; extentsMin: number | number[]; extentsMax: number | number[]; opacity: number; visible: boolean; meshShaderIndex: number; offsetPt0: Uint32Array | null; colormapInvert: boolean; fiberGroupColormap: ColorMap | null; indexBuffer: WebGLBuffer; vertexBuffer: WebGLBuffer; vao: WebGLVertexArrayObject; vaoFiber: WebGLVertexArrayObject; pts: Float32Array; tris?: Uint32Array; layers: NVMeshLayer[]; type: MeshType; data_type?: string; rgba255: Uint8Array; fiberLength?: number; fiberLengths?: Uint32Array; fiberDensity?: Float32Array; fiberDither: number; fiberColor: string; fiberDecimationStride: number; fiberSides: number; fiberRadius: number; fiberOcclusion: number; f32PerVertex: number; fiberMask?: unknown[]; colormap?: ColorMap | LegacyConnectome | string | null; dpg?: ValuesArray | null; dps?: ValuesArray | null; dpv?: ValuesArray | null; hasConnectome: boolean; connectome?: LegacyConnectome | string; indexCount?: number; vertexCount: number; nodeScale: number; edgeScale: number; legendLineThickness: number; nodeColormap: string; edgeColormap: string; nodeColormapNegative?: string; edgeColormapNegative?: string; nodeMinColor?: number; nodeMaxColor?: number; edgeMin?: number; edgeMax?: number; nodes?: LegacyNodes | NVConnectomeNode[]; edges?: number[] | NVConnectomeEdge[]; points?: Point[]; /** * @param pts - a 3xN array of vertex positions (X,Y,Z coordinates). * @param tris - a 3xN array of triangle indices (I,J,K; indexed from zero). Each triangle generated from three vertices. * @param name - a name for this image. Default is an empty string * @param rgba255 - the base color of the mesh. RGBA values from 0 to 255. Default is white * @param opacity - the opacity for this mesh. default is 1 * @param visible - whether or not this image is to be visible * @param gl - WebGL rendering context * @param connectome - specify connectome edges and nodes. Default is null (not a connectome). * @param dpg - Data per group for tractography, see TRK format. Default is null (not tractograpgy) * @param dps - Data per streamline for tractography, see TRK format. Default is null (not tractograpgy) * @param dpv - Data per vertex for tractography, see TRK format. Default is null (not tractograpgy) * @param colorbarVisible - does this mesh display a colorbar * @param anatomicalStructurePrimary - region for mesh. Default is an empty string */ constructor(pts: Float32Array, tris: Uint32Array, name: string, rgba255: Uint8Array, opacity: number, visible: boolean, gl: WebGL2RenderingContext, connectome?: LegacyConnectome | string | null, dpg?: ValuesArray | null, dps?: ValuesArray | null, dpv?: ValuesArray | null, colorbarVisible?: boolean, anatomicalStructurePrimary?: string); initValuesArray(va: ValuesArray): ValuesArray; linesToCylinders(gl: WebGL2RenderingContext, posClrF32: Float32Array, indices: number[]): void; createFiberDensityMap(): void; updateFibers(gl: WebGL2RenderingContext): void; indexNearestXYZmm(Xmm: number, Ymm: number, Zmm: number): number[]; unloadMesh(gl: WebGL2RenderingContext): void; blendColormap(u8: Uint8Array, additiveRGBA: Uint8Array, layer: NVMeshLayer, mn: number, mx: number, lut: Uint8ClampedArray, invert?: boolean): void; updateMesh(gl: WebGL2RenderingContext): void; reverseFaces(gl: WebGL2RenderingContext): void; hierarchicalOrder(): number; decimateFaces(n: number, ntarget: number): void; decimateHierarchicalMesh(gl: WebGL2RenderingContext, order?: number): boolean; setLayerProperty(id: number, key: keyof NVMeshLayer, val: number | string | boolean, gl: WebGL2RenderingContext): Promise<void>; setProperty(key: keyof this, val: number | string | boolean | Uint8Array | number[] | ColorMap | LegacyConnectome | Float32Array, gl: WebGL2RenderingContext): void; generatePosNormClr(pts: Float32Array, tris: Uint32Array, rgba255: Uint8Array): Float32Array; static readMesh(buffer: ArrayBuffer, name: string, gl: WebGL2RenderingContext, opacity?: number, rgba255?: Uint8Array, visible?: boolean): Promise<NVMesh>; static loadLayer(layer: NVMeshLayer, nvmesh: NVMesh): Promise<void>; /** * factory function to load and return a new NVMesh instance from a given URL */ static loadFromUrl({ url, headers, gl, name, opacity, rgba255, visible, layers, buffer }?: Partial<LoadFromUrlParams>): Promise<NVMesh>; static readFileAsync(file: Blob): Promise<ArrayBuffer>; /** * factory function to load and return a new NVMesh instance from a file in the browser * * @returns NVMesh instance */ static loadFromFile({ file, gl, name, opacity, rgba255, visible, layers }?: Partial<LoadFromFileParams>): Promise<NVMesh>; /** * load and return a new NVMesh instance from a base64 encoded string */ loadFromBase64({ base64, gl, name, opacity, rgba255, visible, layers }?: Partial<LoadFromBase64Params>): Promise<NVMesh>; } type TypedNumberArray = Float64Array | Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array; declare class NVUtilities { static arrayBufferToBase64(arrayBuffer: ArrayBuffer): string; static decompress(data: Uint8Array): Promise<Uint8Array>; static decompressToBuffer(data: Uint8Array): Promise<ArrayBuffer>; static readMatV4(buffer: ArrayBuffer, isReplaceDots?: boolean): Promise<Record<string, TypedNumberArray>>; static b64toUint8(base64: string): Uint8Array; static uint8tob64(bytes: Uint8Array): string; static download(content: string | ArrayBuffer, fileName: string, contentType: string): void; static readFileAsync(file: Blob): Promise<ArrayBuffer>; static blobToBase64(blob: Blob): Promise<string>; static decompressBase64String(base64: string): Promise<string>; static compressToBase64String(string: string): Promise<string>; /** * Converts a string into a Uint8Array for use with compression/decompression methods (101arrowz/fflate: MIT License) * @param str The string to encode * @param latin1 Whether or not to interpret the data as Latin-1. This should * not need to be true unless decoding a binary string. * @returns The string encoded in UTF-8/Latin-1 binary */ static strToU8(str: string, latin1?: boolean): Uint8Array; static compress(data: Uint8Array, format?: CompressionFormat): Promise<ArrayBuffer>; static compressStringToArrayBuffer(input: string): Promise<ArrayBuffer>; static isArrayBufferCompressed(buffer: ArrayBuffer): boolean; /** * Converts a Uint8Array to a string (101arrowz/fflate: MIT License) * @param dat The data to decode to string * @param latin1 Whether or not to interpret the data as Latin-1. This should * not need to be true unless encoding to binary string. * @returns The original UTF-8/Latin-1 string */ static strFromU8(dat: Uint8Array, latin1?: boolean): string; static decompressArrayBuffer(buffer: ArrayBuffer): Promise<string>; static arraysAreEqual(a: unknown[], b: unknown[]): boolean; /** * Generate a pre-filled number array. * * @param start - start value * @param stop - stop value * @param step - step value * @returns filled number array */ static range(start: number, stop: number, step: number): number[]; /** * convert spherical AZIMUTH, ELEVATION to Cartesian * @param azimuth - azimuth number * @param elevation - elevation number * @returns the converted [x, y, z] coordinates * @example * xyz = NVUtilities.sph2cartDeg(42, 42) */ static sph2cartDeg(azimuth: number, elevation: number): number[]; static vox2mm(XYZ: number[], mtx: mat4): vec3; } /** * Class to load different mesh formats * @ignore */ declare class NVMeshLoaders { static readTRACT(buffer: ArrayBuffer): TRACT; static readTT(buffer: ArrayBuffer): Promise<TT>; static readTRX(buffer: ArrayBuffer): Promise<TRX>; static readTSF(buffer: ArrayBuffer, n_vert?: number): Float32Array; static readTCK(buffer: ArrayBuffer): TCK; static readTRK(buffer: ArrayB