dcmjs - DICOM Manipulation Library
dcmjs is a comprehensive JavaScript library for manipulating DICOM (Digital Imaging and Communications in Medicine) objects. It supports both browser and Node.js environments and is currently at version 0.50.1. The project maintains an active release cadence, with frequent bug fixes and feature enhancements, often releasing new minor versions every few weeks. A key differentiator of dcmjs is its strong focus on modern DICOM standards, specifically addressing Enhanced Multiframe Images, Segmentation Objects, Parametric Maps, and Structured Reports. It intentionally avoids legacy DICOM components like DIMSE networking (C-STORE, C-FIND) and physical media handling, instead encouraging integration with specialized companion libraries for such tasks. It also does not include image rendering or 3D rendering capabilities, positioning itself as a core data manipulation tool rather than a full-fledged medical imaging application.
Common errors
-
Error: Cannot find module 'dcmjs' or its corresponding type declarations.
cause This typically indicates that the package was not installed, or you are attempting to use CommonJS `require()` syntax in an ESM-only context without proper transpilation or configuration, or vice-versa.fixEnsure `npm install dcmjs` is run. If using Node.js ESM, confirm your `package.json` has `"type": "module"` or use `.mjs` extension. If using CommonJS, ensure your build system correctly handles ESM imports or consider older versions if CJS is strictly required (though dcmjs targets modern ES6). -
Error: Not a valid DICOM P10 file preamble
cause The input data provided to `DicomMessage.read()` or `DicomMessage.readFile()` does not start with the expected 128-byte preamble followed by 'DICM' magic word, or the file metadata is corrupted.fixVerify the integrity of the DICOM file/data. Ensure it's a valid DICOM Part 10 file. Check if the input is correctly passed as a `DataView` or `ArrayBuffer`. -
TypeError: Cannot read properties of undefined (reading 'Value')
cause Attempting to access a DICOM element (e.g., `dicomDict.dict.PatientName.Value`) that does not exist in the parsed DICOM dataset, or the keyword/tag used is incorrect.fixCheck the DICOM file's contents to confirm the presence of the desired tag. Use a DICOM viewer to inspect the dataset. Ensure the keyword matches the DICOM standard tag name or the correct tag number (e.g., `dicomDict.dict['00100010'].Value`).
Warnings
- gotcha dcmjs is explicitly focused on modern DICOM objects (e.g., Enhanced Multiframe Images, SRs). Users attempting to process older or more esoteric DICOM data, especially those relying on legacy transfer syntaxes or structures not explicitly supported, may encounter parsing errors or incomplete data extraction.
- breaking The project is still considered 'work-in-progress' and is pre-1.0 (currently 0.50.1). While semantic versioning is generally followed for new releases, breaking changes may occur more frequently than in a stable 1.0+ library. Always review release notes for significant updates.
- gotcha dcmjs does not handle DIMSE (legacy DICOM networking protocols like C-STORE) or image rendering directly. Attempting to use it for these purposes will lead to a lack of functionality.
Install
-
npm install dcmjs -
yarn add dcmjs -
pnpm add dcmjs
Imports
- DicomMessage
const DicomMessage = require('dcmjs').DicomMessage;import { DicomMessage } from 'dcmjs'; - DicomDict
const DicomDict = require('dcmjs').DicomDict;import { DicomDict } from 'dcmjs'; - utilities
const utilities = require('dcmjs').utilities;import { utilities } from 'dcmjs';
Quickstart
import { DicomMessage, utilities } from 'dcmjs';
// A minimal, dummy DICOM P10 byte array for demonstration purposes.
// In a real application, this would come from a file or network stream.
const dummyDicomP10 = new Uint8Array([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 128-byte preamble
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x44, 0x49, 0x43, 0x4d, // 'DICM' prefix
// (0002,0000) File Meta Information Group Length, UL, 4 bytes = 48
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
// (0002,0010) Transfer Syntax UID, UI, Explicit VR Little Endian (1.2.840.10008.1.2.1)
0x02, 0x00, 0x10, 0x00, 0x55, 0x49, 0x1A, 0x00,
0x31, 0x2E, 0x32, 0x2E, 0x38, 0x34, 0x30, 0x2E, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2E, 0x31, 0x2E,
0x32, 0x2E, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Padded
// (0002,0002) Media Storage SOP Class UID, UI, CT Image Storage (1.2.840.10008.5.1.4.1.1.2)
0x02, 0x00, 0x02, 0x00, 0x55, 0x49, 0x1A, 0x00,
0x31, 0x2E, 0x32, 0x2E, 0x38, 0x34, 0x30, 0x2E, 0x31, 0x30, 0x30, 0x30, 0x38, 0x2E, 0x35, 0x2E,
0x31, 0x2E, 0x34, 0x2E, 0x31, 0x2E, 0x31, 0x2E, 0x32, 0x00, // Padded
// (0010,0010) Patient's Name, PN, 'JOHN^DOE'
0x10, 0x00, 0x10, 0x00, 0x50, 0x4E, 0x08, 0x00, // PN, Length = 8
0x4A, 0x4F, 0x48, 0x4E, 0x5E, 0x44, 0x4F, 0x45 // JOHN^DOE
]);
async function parseDicomData() {
try {
// DicomMessage.read expects a DataView, ArrayBuffer, or ArrayBufferView
const dicomDataView = new DataView(dummyDicomP10.buffer);
const dicomDict = DicomMessage.read(dicomDataView);
console.log('DICOM parsing successful.');
// Accessing elements by their keyword (case-insensitive) or tag
const patientName = dicomDict.dict.PatientName.Value;
console.log(`Patient Name: ${patientName[0]}`);
const transferSyntaxUID = dicomDict.dict.TransferSyntaxUID.Value;
console.log(`Transfer Syntax UID: ${transferSyntaxUID[0]}`);
// Example of using a utility function (e.g., to convert DICOM date/time)
const formattedDate = utilities.formatDICOMDate('20260417');
console.log(`Formatted Date '20260417': ${formattedDate}`);
} catch (error) {
console.error('Error parsing DICOM data:', error);
}
}
parseDicomData();