Welcome to the Swift DICOM Decoder. This guide helps you start working with DICOM files in Swift.
DICOM (Digital Imaging and Communications in Medicine) is the international standard for storing and transmitting medical images. Common sources include:
- CT scanners
- MRI
- Digital X-ray
- Ultrasound
- Mammography
A DICOM file (.dcm) contains:
- Pixel data (the image itself)
- Metadata (patient name, exam date, scanner settings, and more)
Before you start, ensure you have:
- Xcode 14.0+
- Swift 5.9+
- macOS 12+ or iOS 13+
- Basic Swift knowledge
- At least one DICOM file to test (
.dcm)
- Public datasets such as TCIA
- DICOM Sample Images
- Generated test files with tools like dcmtk
- Open your project in Xcode.
- Go to File -> Add Packages...
- Enter the repository URL:
https://github.com/ThalesMMS/DICOM-Decoder.git - Select version
1.0.0or later. - Click Add Package.
Add to Package.swift:
dependencies: [
.package(url: "https://github.com/ThalesMMS/DICOM-Decoder.git", from: "1.0.0")
]And in your target:
.target(
name: "MyApp",
dependencies: [
.product(name: "DicomCore", package: "DICOM-Decoder")
]
)In any Swift file where you want to use the decoder:
import DicomCoreCreate a simple program that reads a DICOM file and prints basic information.
import DicomCore
func readDICOMFile() {
do {
let decoder = try DCMDecoder(contentsOfFile: "/path/to/your/file.dcm")
print("DICOM file loaded")
print("Dimensions: \(decoder.width) x \(decoder.height) pixels")
print("Bit depth: \(decoder.bitDepth) bits")
print("Modality: \(decoder.info(for: .modality))")
print("Patient Name: \(decoder.info(for: .patientName))")
} catch {
print("Error loading DICOM file: \(error)")
}
}
readDICOMFile()Expected output:
DICOM file loaded
Dimensions: 512 x 512 pixels
Bit depth: 16 bits
Modality: CT
Patient Name: John Doe
For iOS 13+ and macOS 10.15+, you can use the asynchronous API:
import DicomCore
func readDICOMAsync() async {
do {
let decoder = try await DCMDecoder(contentsOfFile: "/path/to/your/file.dcm")
print("File loaded")
print("Dimensions: \(decoder.width) x \(decoder.height)")
} catch {
print("Error loading file: \(error)")
}
}
Task {
await readDICOMAsync()
}Validate the file before loading it fully.
import DicomCore
func validateAndLoad(path: String) {
let decoder = DCMDecoder()
let validation = decoder.validateDICOMFile(path)
if !validation.isValid {
print("Invalid file:")
for issue in validation.issues {
print(" - \(issue)")
}
return
}
print("Valid file. Loading...")
do {
let decoder = try DCMDecoder(contentsOfFile: path)
let status = decoder.getValidationStatus()
print("Status:")
print(" - Valid: \(status.isValid)")
print(" - Dimensions: \(status.width) x \(status.height)")
print(" - Contains pixels: \(status.hasPixels)")
print(" - Compressed: \(status.isCompressed)")
} catch {
print("Error loading file: \(error)")
}
}+-----------------------------+
| Preamble (128 bytes) |
+-----------------------------+
| "DICM" (4 bytes) | <- DICOM signature
+-----------------------------+
| Meta Information | <- File information
+-----------------------------+
| Dataset (Tags) | <- Medical metadata
| - Patient Info |
| - Study Info |
| - Series Info |
| - Image Info |
+-----------------------------+
| Pixel Data | <- Image pixels
+-----------------------------+
Tags are numeric identifiers for each metadata field. Format: (GGGG,EEEE)
Common examples:
| Tag | DicomTag Enum | Description |
|---|---|---|
| (0010,0010) | .patientName |
Patient Name |
| (0010,0020) | .patientID |
Patient ID |
| (0008,0060) | .modality |
Modality (CT, MR, ...) |
| (0020,000D) | .studyInstanceUID |
Study Instance UID |
| (0028,0010) | .rows |
Rows (height) |
| (0028,0011) | .columns |
Columns (width) |
Using tags in code:
// Recommended: Type-safe DicomTag enum
let name = decoder.info(for: .patientName)
let patient = decoder.getPatientInfo()
print(patient["Name"] ?? "Unknown")
if let height = decoder.intValue(for: .rows) {
print("Height: \(height) pixels")
}Window/Level controls brightness and contrast of DICOM images.
- Level (Center): controls brightness
- Width: controls contrast
Pixels below window Pixels inside window Pixels above window
(black) (grayscale) (white)
v v v
===========================================================
^ ^
Level - Width/2 Level + Width/2
Practical example:
guard let pixels16 = decoder.getPixels16() else {
print("No pixel data")
return
}
let lung = DCMWindowingProcessor.getPresetValues(preset: .lung)
let lungImage = DCMWindowingProcessor.applyWindowLevel(
pixels16: pixels16,
center: lung.center,
width: lung.width
)
if let optimal = decoder.calculateOptimalWindow() {
let optimizedImage = DCMWindowingProcessor.applyWindowLevel(
pixels16: pixels16,
center: optimal.center,
width: optimal.width
)
}Supported modalities and notes:
| Code | Name | Description |
|---|---|---|
| CT | Computed Tomography | Cross-sectional images |
| MR | Magnetic Resonance | Soft tissue imaging |
| CR | Computed Radiography | Digital X-ray |
| DX | Digital X-Ray | Digital X-ray |
| US | Ultrasound | Often color and multi-frame |
| MG | Mammography | High-resolution breast imaging |
| PT | PET Scan | Positron emission tomography |
Example:
let modality = decoder.info(for: .modality)
switch modality {
case "CT":
print("Computed Tomography")
case "MR":
print("Magnetic Resonance")
case "CR", "DX":
print("Digital X-ray")
case "US":
print("Ultrasound")
default:
print("Modality: \(modality)")
}In CT, pixel values represent density in Hounsfield Units (HU):
| Material | Typical HU |
|---|---|
| Air | -1000 |
| Lung | -500 to -700 |
| Fat | -100 to -50 |
| Water | 0 |
| Blood | +30 to +45 |
| Muscle | +10 to +40 |
| Soft Tissue | +100 to +300 |
| Bone | +700 to +3000 |
Convert pixels to HU:
let pixelValue: Double = 1024.0
let hu = decoder.applyRescale(to: pixelValue)
print("Pixel \(pixelValue) = \(hu) HU")
if hu < -500 {
print("Likely air or lung")
} else if hu > 700 {
print("Likely bone")
}Explore additional materials:
- Complete Usage Examples
- Batch processing
- Thumbnail generation
- Image quality analysis
- DICOM Glossary
- Definitions of technical terms
- Troubleshooting - fixes for common issues
- API Reference - generate DocC locally with
swift package generate-documentation --target DicomCore - Project Architecture - code organization
- DICOM Standard - official specification
- Innolitics DICOM Browser - browse tags
- DCMTK Tools - command-line utilities