or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-line-interface.mdcpp-library-api.mdindex.mdjavascript-api.md

javascript-api.mddocs/

0

# JavaScript API

1

2

Browser-based DICOM to NIfTI conversion using WebAssembly. The JavaScript API provides an object-oriented interface for converting medical imaging data directly in the browser without requiring server uploads.

3

4

## Installation

5

6

```bash

7

npm install @niivue/dcm2niix

8

```

9

10

For JPEG-LS and JPEG2000 support:

11

12

```bash

13

npm install @niivue/dcm2niix

14

# Then import from the jpeg build

15

```

16

17

## Core Imports

18

19

Standard import (basic JPEG support):

20

21

```javascript

22

import { Dcm2niix } from '@niivue/dcm2niix';

23

```

24

25

Enhanced import (JPEG-LS and JPEG2000 support):

26

27

```javascript

28

import { Dcm2niix } from '@niivue/dcm2niix/jpeg';

29

```

30

31

## Basic Usage

32

33

```javascript

34

import { Dcm2niix } from '@niivue/dcm2niix';

35

36

// Initialize converter

37

const dcm2niix = new Dcm2niix();

38

await dcm2niix.init();

39

40

// Setup file input handler

41

const fileInput = document.getElementById('fileInput'); // with webkitdirectory and multiple attributes

42

fileInput.addEventListener('change', async (event) => {

43

const files = event.target.files;

44

45

try {

46

const convertedFiles = await dcm2niix

47

.input(files)

48

.bids('y') // Generate BIDS sidecar

49

.verbose('y') // Enable verbose output

50

.gzip('y') // Compress output

51

.run();

52

53

// Process converted files

54

convertedFiles.forEach(file => {

55

console.log(`Converted: ${file.name} (${file.type})`);

56

// Create download link, display in viewer, etc.

57

});

58

} catch (error) {

59

console.error('Conversion failed:', error.message);

60

}

61

});

62

```

63

64

## Capabilities

65

66

### Dcm2niix Class

67

68

Main class for DICOM to NIfTI conversion in the browser.

69

70

```javascript { .api }

71

/**

72

* Main dcm2niix conversion class

73

*/

74

class Dcm2niix {

75

constructor();

76

77

/**

78

* Initialize WebAssembly worker

79

* @returns Promise that resolves when worker is ready

80

*/

81

init(): Promise<boolean>;

82

83

/**

84

* Create processor for file input

85

* @param fileList - Files from input element or file array

86

* @returns Processor instance for chaining options

87

*/

88

input(fileList: FileList | File[]): Processor;

89

90

/**

91

* Create processor for webkit directory input

92

* @param fileList - Files from webkitdirectory input

93

* @returns Processor instance for chaining options

94

*/

95

inputFromWebkitDirectory(fileList: FileList | File[]): Processor;

96

97

/**

98

* Create processor for drag-and-drop files

99

* @param items - DataTransferItem array from drop event

100

* @returns Processor instance for chaining options

101

*/

102

inputFromDropItems(items: DataTransferItem[]): Processor;

103

}

104

```

105

106

**Usage Example:**

107

108

```javascript

109

const dcm2niix = new Dcm2niix();

110

111

// Initialize (required before use)

112

await dcm2niix.init();

113

114

// Handle different input sources

115

const processor1 = dcm2niix.input(fileInputElement.files);

116

const processor2 = dcm2niix.inputFromWebkitDirectory(directoryFiles);

117

const processor3 = dcm2niix.inputFromDropItems(dropEvent.dataTransfer.items);

118

```

119

120

### Processor Class

121

122

Handles conversion configuration and execution. All configuration methods return the processor instance for method chaining.

123

124

```javascript { .api }

125

/**

126

* Conversion processor with chainable configuration methods

127

*/

128

class Processor {

129

/**

130

* Execute the conversion

131

* @returns Promise resolving to array of converted files

132

*/

133

run(): Promise<File[]>;

134

135

// === Core Options ===

136

137

/**

138

* BIDS sidecar generation

139

* @param value - 'y'=generate, 'n'=no sidecar, 'o'=only sidecar (no NIfTI)

140

*/

141

b(value: 'y' | 'n' | 'o'): Processor;

142

bids(value: 'y' | 'n' | 'o'): Processor;

143

144

/**

145

* Verbosity level

146

* @param value - 'n'/'0'=quiet, 'y'/'1'=verbose, '2'=very verbose

147

*/

148

v(value: 'n' | 'y' | '0' | '1' | '2'): Processor;

149

verbose(value: 'n' | 'y' | '0' | '1' | '2'): Processor;

150

151

/**

152

* Compression options

153

* @param value - 'y'=pigz, 'o'=optimal, 'i'=internal, 'n'=none, '3'=no 3D

154

*/

155

z(value: 'y' | 'o' | 'i' | 'n' | '3'): Processor;

156

gzip(value: 'y' | 'o' | 'i' | 'n' | '3'): Processor;

157

158

// === Format Options ===

159

160

/**

161

* Export format selection

162

* @param value - 'y'=NRRD, 'o'=MGH, 'j'=JSON, 'b'=BJNIfTI, 'n'=NIfTI

163

*/

164

e(value: 'y' | 'n' | 'o' | 'j' | 'b'): Processor;

165

exportFormat(value: 'y' | 'n' | 'o' | 'j' | 'b'): Processor;

166

167

/**

168

* Filename format with DICOM field placeholders

169

* @param format - Format string with %placeholders

170

*/

171

f(format: string): Processor;

172

filenameformat(format: string): Processor;

173

174

// === Processing Options ===

175

176

/**

177

* Adjacent DICOMs for faster conversion

178

* @param value - 'y'=assume same folder, 'n'=search subdirectories

179

*/

180

a(value: 'y' | 'n'): Processor;

181

adjacent(value: 'y' | 'n'): Processor;

182

183

/**

184

* Ignore derived, localizer and 2D images

185

* @param value - 'y'=ignore, 'n'=include all

186

*/

187

i(value: 'y' | 'n'): Processor;

188

ignoreDerived(value: 'y' | 'n'): Processor;

189

190

/**

191

* Merge 2D slices from same series

192

* @param value - 'n'/'0'=no merge, 'y'/'1'=force merge, '2'=auto merge

193

*/

194

m(value: 'n' | 'y' | '0' | '1' | '2'): Processor;

195

merge2DSlices(value: 'n' | 'y' | '0' | '1' | '2'): Processor;

196

197

/**

198

* Single file mode

199

* @param value - 'y'=process only one file, 'n'=process all files

200

*/

201

s(value: 'y' | 'n'): Processor;

202

singleFileMode(value: 'y' | 'n'): Processor;

203

204

// === Data Processing ===

205

206

/**

207

* Lossless 16-bit integer scaling

208

* @param value - 'y'=scale, 'n'=uint16->int16, 'o'=preserve original

209

*/

210

l(value: 'y' | 'n' | 'o'): Processor;

211

losslessScale(value: 'y' | 'n' | 'o'): Processor;

212

213

/**

214

* Philips precise float scaling

215

* @param value - 'y'=precise float, 'n'=display scaling

216

*/

217

p(value: 'y' | 'n'): Processor;

218

philipsPreciseFloat(value: 'y' | 'n'): Processor;

219

220

/**

221

* Crop 3D acquisitions

222

* @param value - 'y'=crop, 'n'=no crop, 'i'=ignore (no crop/rotate)

223

*/

224

x(value: 'y' | 'n' | 'i'): Processor;

225

crop(value: 'y' | 'n' | 'i'): Processor;

226

227

// === Metadata Options ===

228

229

/**

230

* Comment for NIfTI aux_file field

231

* @param comment - Text comment (up to 24 characters)

232

*/

233

c(comment: string): Processor;

234

comment(comment: string): Processor;

235

236

/**

237

* BIDS anonymization

238

* @param value - 'y'=anonymize BIDS, 'n'=include patient details

239

*/

240

ba(value: 'y' | 'n'): Processor;

241

bidsAnonymize(value: 'y' | 'n'): Processor;

242

243

// === Advanced Options ===

244

245

/**

246

* Compression level for gzip

247

* @param level - Compression level 1-9 (1=fastest, 9=smallest)

248

*/

249

compressionLevel(level: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9): Processor;

250

251

/**

252

* Directory search depth

253

* @param depth - Search depth 0-9

254

*/

255

d(depth: number): Processor;

256

directorySearchDepth(depth: number): Processor;

257

258

/**

259

* Convert specific series by CRC number

260

* @param crc - Series CRC number to convert

261

*/

262

n(crc: number): Processor;

263

seriesCRC(crc: number): Processor;

264

265

/**

266

* Search directory behavior

267

* @param value - 'y'=show count, 'l'=list files, 'n'=no search

268

*/

269

q(value: 'y' | 'l' | 'n'): Processor;

270

searchDirectory(value: 'y' | 'l' | 'n'): Processor;

271

272

/**

273

* Rename instead of convert

274

* @param value - 'y'=rename only, 'n'=convert

275

*/

276

r(value: 'y' | 'n'): Processor;

277

renameOnly(value: 'y' | 'n'): Processor;

278

279

/**

280

* Write behavior for name conflicts

281

* @param behavior - 0=skip, 1=overwrite, 2=add suffix

282

*/

283

w(behavior: 0 | 1 | 2): Processor;

284

writeBehavior(behavior: 0 | 1 | 2): Processor;

285

286

/**

287

* Byte order

288

* @param value - 'y'=big-endian, 'n'=little-endian, 'o'=optimal/native

289

*/

290

bigEndian(value: 'y' | 'n' | 'o'): Processor;

291

292

/**

293

* Ignore trigger times

294

*/

295

ignoreTriggerTimes(): Processor;

296

297

/**

298

* Omit filename post-fixes

299

*/

300

terse(): Processor;

301

302

/**

303

* Slicer format features

304

*/

305

xml(): Processor;

306

307

/**

308

* Show version information

309

*/

310

version(): Processor;

311

}

312

```

313

314

## Advanced Usage Examples

315

316

### File Input Handling

317

318

```javascript

319

import { Dcm2niix } from '@niivue/dcm2niix';

320

321

const dcm2niix = new Dcm2niix();

322

await dcm2niix.init();

323

324

// Directory input with webkitdirectory

325

const directoryInput = document.getElementById('dirInput');

326

directoryInput.addEventListener('change', async (event) => {

327

const files = event.target.files;

328

const results = await dcm2niix.inputFromWebkitDirectory(files).run();

329

console.log('Converted files:', results);

330

});

331

332

// Drag and drop handling

333

const dropZone = document.getElementById('dropZone');

334

dropZone.addEventListener('drop', async (event) => {

335

event.preventDefault();

336

const items = event.dataTransfer.items;

337

338

// Set custom relative paths for drop events

339

const filesWithPaths = [];

340

for (let item of items) {

341

const file = item.getAsFile();

342

if (file) {

343

file._webkitRelativePath = file.name; // Custom property for worker

344

filesWithPaths.push(file);

345

}

346

}

347

348

const results = await dcm2niix.inputFromDropItems(filesWithPaths).run();

349

});

350

```

351

352

### Complex Conversion Pipeline

353

354

```javascript

355

// Advanced conversion with multiple options

356

const results = await dcm2niix

357

.input(files)

358

.verbose('2') // Maximum verbosity

359

.bids('y') // Generate BIDS sidecar

360

.bidsAnonymize('y') // Anonymize BIDS output

361

.gzip('o') // Optimal compression

362

.compressionLevel(9) // Maximum compression

363

.filenameformat('%p_%t_%s') // Custom filename format

364

.ignoreDerived('y') // Skip derived images

365

.merge2DSlices('2') // Auto-merge 2D slices

366

.losslessScale('y') // Scale 16-bit data

367

.crop('y') // Crop 3D acquisitions

368

.comment('Processed by web app') // Add comment

369

.run();

370

371

// Process results by file type

372

results.forEach(file => {

373

if (file.name.endsWith('.nii.gz')) {

374

console.log('NIfTI file:', file.name);

375

// Display in viewer, trigger download, etc.

376

} else if (file.name.endsWith('.json')) {

377

console.log('BIDS sidecar:', file.name);

378

// Parse JSON metadata

379

} else if (file.name.endsWith('.bval') || file.name.endsWith('.bvec')) {

380

console.log('DTI file:', file.name);

381

// Handle diffusion data

382

}

383

});

384

```

385

386

### Error Handling

387

388

```javascript

389

try {

390

const results = await dcm2niix

391

.input(files)

392

.bids('y')

393

.run();

394

395

if (results.length === 0) {

396

console.warn('No files were converted - check input files');

397

}

398

399

} catch (error) {

400

if (error.message.includes('exit code')) {

401

// dcm2niix processing error

402

const exitCode = error.message.match(/exit code (\d+)/)?.[1];

403

switch (exitCode) {

404

case '2':

405

console.error('No valid DICOM files found');

406

break;

407

case '4':

408

console.error('Corrupt DICOM file encountered');

409

break;

410

default:

411

console.error('Conversion failed:', error.message);

412

}

413

} else if (error.message.includes('Worker')) {

414

console.error('WebAssembly initialization failed:', error.message);

415

} else {

416

console.error('Unexpected error:', error.message);

417

}

418

}

419

```

420

421

### Filename Format Placeholders

422

423

When using the `filenameformat()` method, these placeholders are available:

424

425

```javascript

426

dcm2niix

427

.input(files)

428

.filenameformat('%p_%t_%s_%e') // protocol_time_series_echo

429

.run();

430

```

431

432

Available placeholders:

433

- `%a` - Antenna (coil) name

434

- `%b` - Basename

435

- `%c` - Comments

436

- `%d` - Description

437

- `%e` - Echo number

438

- `%f` - Folder name

439

- `%g` - Accession number

440

- `%i` - Patient ID

441

- `%j` - Series Instance UID

442

- `%k` - Study Instance UID

443

- `%m` - Manufacturer

444

- `%n` - Patient name

445

- `%o` - Media Object Instance UID

446

- `%p` - Protocol name

447

- `%r` - Instance number

448

- `%s` - Series number

449

- `%t` - Time

450

- `%u` - Acquisition number

451

- `%v` - Vendor

452

- `%x` - Study ID

453

- `%z` - Sequence name

454

455

## Types

456

457

```typescript { .api }

458

/**

459

* File input types supported by dcm2niix

460

*/

461

type FileInput = FileList | File[] | DataTransferItem[];

462

463

/**

464

* Boolean option values

465

*/

466

type BooleanOption = 'y' | 'n';

467

468

/**

469

* Verbosity levels

470

*/

471

type VerbosityLevel = 'n' | 'y' | '0' | '1' | '2';

472

473

/**

474

* Compression options

475

*/

476

type CompressionOption = 'y' | 'o' | 'i' | 'n' | '3';

477

478

/**

479

* Export format options

480

*/

481

type ExportFormat = 'y' | 'n' | 'o' | 'j' | 'b';

482

483

/**

484

* Merge options for 2D slices

485

*/

486

type MergeOption = 'n' | 'y' | '0' | '1' | '2';

487

488

/**

489

* Scaling options for 16-bit data

490

*/

491

type ScalingOption = 'y' | 'n' | 'o';

492

493

/**

494

* Crop options for 3D data

495

*/

496

type CropOption = 'y' | 'n' | 'i';

497

498

/**

499

* Byte order options

500

*/

501

type ByteOrderOption = 'y' | 'n' | 'o';

502

503

/**

504

* Search directory options

505

*/

506

type SearchOption = 'y' | 'l' | 'n';

507

508

/**

509

* Write behavior for file conflicts

510

*/

511

type WriteBehavior = 0 | 1 | 2;

512

513

/**

514

* Compression levels

515

*/

516

type CompressionLevel = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;

517

518

/**

519

* Conversion result extends File with guaranteed properties

520

*/

521

interface ConversionResult extends File {

522

readonly name: string; // Output filename

523

readonly type: string; // MIME type based on extension

524

readonly size: number; // File size in bytes

525

}

526

```

527

528

## Browser Compatibility

529

530

The JavaScript API requires:

531

- **WebAssembly**: Supported in all modern browsers

532

- **Web Workers**: For background processing

533

- **File API**: For file input handling

534

- **ES6 Modules**: For import/export syntax

535

536

Minimum browser versions:

537

- Chrome 57+

538

- Firefox 52+

539

- Safari 11+

540

- Edge 16+