DICOM Basics using Java - Understanding Print Operations
Introduction
This is part of my series of articles on the DICOM standard. In this tutorial, we'll explore DICOM Print Management, which enables sending medical images to film printers or digital printers. While digital viewing has become predominant, DICOM printing is still used in many clinical settings for creating hard copies and film jackets.
DICOM Print uses a hierarchical model with Film Sessions, Film Boxes, and Image Boxes to represent the print job structure.
Prerequisites
Before you begin, ensure you have the following:
- Java JDK installed (Java 8 or later)
- PixelMed Java DICOM Toolkit
- A DICOM print server or printer (optional - demo shows workflow)
- You can find all the code demonstrated in this tutorial on GitHub here
“Simplicity is the ultimate sophistication.” ~ Leonardo da Vinci
The Theory Behind DICOM Print
DICOM Print Management may seem anachronistic in an age of digital displays, but it implements sophisticated concepts in device-independent imaging and color management that remain relevant. Understanding these principles helps even when working with modern display systems.
The Grayscale Standard Display Function (GSDF)
Medical imaging requires precise control over how pixel values map to displayed luminance. The human visual system perceives brightness logarithmically, not linearly - we're more sensitive to differences in dark regions than bright regions. DICOM PS3.14 defines the Grayscale Standard Display Function (GSDF), which ensures that equal steps in the digital input produce perceptually equal steps in displayed brightness.
For film printers, this is implemented through carefully characterized Presentation LUTs that compensate for the non-linear response of film and the viewing lightbox luminance. The same principles now apply to calibrated medical displays.
The Print Session Model
DICOM Print's hierarchical model (Session → Film Box → Image Box) reflects how physical printing actually works:
- Film Session: The overall "print job" with settings like number of copies and medium type
- Film Box: A single sheet of film (or page) with layout and orientation
- Image Box: A position on the film where an image is placed
This separation of concerns allows flexible layouts (multiple images per sheet) while maintaining clear ownership of resources. The server tracks which Image Boxes belong to which Film Box, enabling proper cleanup when a print job completes or fails.
Why Film Persists in Some Settings
Despite digital viewing dominance, film printing continues in specific scenarios:
- Regulatory Requirements: Some jurisdictions require physical copies for certain procedures
- Patient Copies: Patients may request film copies to take to other facilities
- Operating Room Use: Sterile environments where displays may be impractical
- Developing Regions: Areas without reliable electricity or PACS infrastructure
- Mammography: Some radiologists still prefer film for subtle findings
Print Management Hierarchy
DICOM Print uses a three-level hierarchy:
Key SOP Classes
Print Management uses several SOP Classes:
| SOP Class | UID | Purpose |
|---|---|---|
| Basic Film Session | 1.2.840.10008.5.1.1.1 | Print job settings |
| Basic Film Box | 1.2.840.10008.5.1.1.2 | Film sheet settings |
| Basic Grayscale Image Box | 1.2.840.10008.5.1.1.4 | Grayscale image position |
| Basic Color Image Box | 1.2.840.10008.5.1.1.4.1 | Color image position |
| Printer SOP Class | 1.2.840.10008.5.1.1.16 | Printer status |
| Basic Grayscale Print Meta | 1.2.840.10008.5.1.1.9 | Meta SOP Class |
Print Operations (DIMSE)
Print Management uses N-DIMSE operations:
| Operation | Purpose |
|---|---|
| N-CREATE | Create Film Session or Film Box |
| N-SET | Set image data in Image Box |
| N-ACTION | Trigger print action |
| N-DELETE | Delete session/box after printing |
| N-GET | Query printer status |
Step 1: Setting Up the Print Demo
Here's how to establish a print connection and demonstrate the workflow:
package com.saravanansubramanian.dicom.pixelmedtutorial;
import java.util.LinkedList;
import com.pixelmed.dicom.*;
import com.pixelmed.network.*;
public class DicomPrintDemo {
// Print Management SOP Class UIDs
private static final String BASIC_FILM_SESSION = "1.2.840.10008.5.1.1.1";
private static final String BASIC_FILM_BOX = "1.2.840.10008.5.1.1.2";
private static final String BASIC_GRAYSCALE_IMAGE_BOX = "1.2.840.10008.5.1.1.4";
private static final String PRINTER_SOP_CLASS = "1.2.840.10008.5.1.1.16";
private static final String BASIC_GRAYSCALE_PRINT_META = "1.2.840.10008.5.1.1.9";
public static void main(String[] args) {
try {
System.out.println("=== DICOM Print Management Demo ===\n");
// Print server connection parameters
String printerHost = "localhost";
int printerPort = 104;
String printerAETitle = "PRINT_SCP";
String localAETitle = "PRINT_SCU";
System.out.println("Connecting to DICOM printer...");
System.out.println("Host: " + printerHost + ":" + printerPort);
System.out.println("AE Title: " + printerAETitle);
// Build presentation contexts for print
LinkedList<PresentationContext> presentationContexts =
buildPrintPresentationContexts();
// Create association
Association association = AssociationFactory.createNewAssociation(
printerHost,
printerPort,
printerAETitle,
localAETitle,
presentationContexts,
null, false, null, 0, 0
);
if (association != null) {
System.out.println("Association established.\n");
demonstratePrintWorkflow();
association.release();
System.out.println("\nAssociation released.");
} else {
System.out.println("Failed to connect to printer.");
demonstratePrintWorkflow();
}
} catch (Exception e) {
System.out.println("Note: DICOM Print requires a print server.");
System.out.println("Error: " + e.getMessage());
demonstratePrintWorkflow();
}
}
}
Step 2: Building Presentation Contexts
Print operations require specific presentation contexts:
private static LinkedList<PresentationContext> buildPrintPresentationContexts() {
LinkedList<PresentationContext> presentationContexts = new LinkedList<>();
byte pcId = 1; // DICOM requires presentation context IDs to be odd numbers
// Basic Grayscale Print Meta SOP Class
presentationContexts.add(new PresentationContext(
pcId,
BASIC_GRAYSCALE_PRINT_META,
TransferSyntax.ImplicitVRLittleEndian
));
pcId += 2;
// Basic Film Session
presentationContexts.add(new PresentationContext(
pcId,
BASIC_FILM_SESSION,
TransferSyntax.ImplicitVRLittleEndian
));
pcId += 2;
// Basic Film Box
presentationContexts.add(new PresentationContext(
pcId,
BASIC_FILM_BOX,
TransferSyntax.ImplicitVRLittleEndian
));
pcId += 2;
// Basic Grayscale Image Box
presentationContexts.add(new PresentationContext(
pcId,
BASIC_GRAYSCALE_IMAGE_BOX,
TransferSyntax.ImplicitVRLittleEndian
));
pcId += 2;
// Printer SOP Class (for status)
presentationContexts.add(new PresentationContext(
pcId,
PRINTER_SOP_CLASS,
TransferSyntax.ImplicitVRLittleEndian
));
return presentationContexts;
}
Step 3: The Print Workflow
A complete print workflow involves these steps:
private static void demonstratePrintWorkflow() {
System.out.println("\n=== DICOM Print Workflow ===\n");
System.out.println("Step 1: N-CREATE Film Session");
System.out.println("-----------------------------------");
System.out.println("Film Session attributes:");
System.out.println(" Number of Copies: 1");
System.out.println(" Print Priority: HIGH");
System.out.println(" Medium Type: BLUE FILM");
System.out.println(" Film Destination: MAGAZINE");
System.out.println("\nStep 2: N-CREATE Film Box");
System.out.println("-----------------------------------");
System.out.println("Film Box attributes:");
System.out.println(" Image Display Format: STANDARD\\1,1 (1x1 images)");
System.out.println(" Film Orientation: PORTRAIT");
System.out.println(" Film Size ID: 14INX17IN");
System.out.println(" Magnification Type: REPLICATE");
System.out.println(" Border Density: BLACK");
System.out.println(" Empty Image Density: BLACK");
System.out.println("\nStep 3: N-SET Image Box (for each image)");
System.out.println("-----------------------------------");
System.out.println("Image Box attributes:");
System.out.println(" Image Position: 1");
System.out.println(" Polarity: NORMAL");
System.out.println(" Requested Image Size: (computed)");
System.out.println(" + Pixel Data from source image");
System.out.println("\nStep 4: N-ACTION on Film Box (Print)");
System.out.println("-----------------------------------");
System.out.println("Action Type ID: 1 (Print)");
System.out.println("This triggers actual printing.");
System.out.println("\nStep 5: N-DELETE Film Session (Cleanup)");
System.out.println("-----------------------------------");
System.out.println("Releases printer resources.");
}
Step 4: Building Film Session Attributes
The Film Session defines overall print job settings:
private static AttributeList buildFilmSessionAttributes() {
AttributeList list = new AttributeList();
try {
// Number of copies
Attribute copies = new IntegerStringAttribute(TagFromName.NumberOfCopies);
copies.addValue("1");
list.put(copies);
// Print priority: LOW, MED, HIGH
Attribute priority = new CodeStringAttribute(TagFromName.PrintPriority);
priority.addValue("HIGH");
list.put(priority);
// Medium type
Attribute medium = new CodeStringAttribute(TagFromName.MediumType);
medium.addValue("BLUE FILM");
list.put(medium);
// Film destination
Attribute destination = new CodeStringAttribute(TagFromName.FilmDestination);
destination.addValue("MAGAZINE");
list.put(destination);
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
Film Layout Options
The Image Display Format attribute controls how images are arranged on film:
| Format | Description |
|---|---|
| STANDARD\1,1 | 1 image per film |
| STANDARD\2,2 | 4 images (2x2 grid) |
| STANDARD\3,3 | 9 images (3x3 grid) |
| STANDARD\4,4 | 16 images (4x4 grid) |
| STANDARD\2,3 | 6 images (2 cols x 3 rows) |
| ROW\1,2,3 | Variable row layout (1+2+3 images) |
| COL\1,2,3 | Variable column layout |
Film Size Options
Common film sizes supported by DICOM printers:
| Size ID | Dimensions |
|---|---|
| 8INX10IN | 8” x 10” |
| 10INX12IN | 10” x 12” |
| 10INX14IN | 10” x 14” |
| 11INX14IN | 11” x 14” |
| 14INX14IN | 14” x 14” |
| 14INX17IN | 14” x 17” |
| 24CMX30CM | 24cm x 30cm |
| A3, A4 | Standard paper sizes |
Medium Types
Different media for different clinical needs:
| Medium | Use Case |
|---|---|
| PAPER | Paper printouts |
| CLEAR FILM | Transparent film |
| BLUE FILM | Blue-tinted film (common) |
| MAMMO CLEAR FILM | Mammography clear film |
| MAMMO BLUE FILM | Mammography blue film |
Film Orientation and Polarity
Additional display settings:
| Attribute | Options |
|---|---|
| Film Orientation | PORTRAIT, LANDSCAPE |
| Polarity | NORMAL, REVERSE |
| Magnification Type | REPLICATE, BILINEAR, CUBIC, NONE |
| Border Density | BLACK, WHITE |
| Empty Image Density | BLACK, WHITE |
Important Considerations
- Printer Capability: Query printer status before sending jobs
- Image Box Assignment: Server returns Image Box SOP Instance UIDs when Film Box is created
- Pixel Data: Must match printer's expected format and bit depth
- Resource Cleanup: Always delete Film Session after printing
- Error Handling: Check response status for each operation
Print Job Sequence
Complete sequence for printing multiple images:
Conclusion
DICOM Print Management provides a standardized way to send medical images to film printers. While the workflow involves multiple steps and SOP Classes, the hierarchical model (Session > Box > Image) maps naturally to the physical printing process.
Understanding the print workflow and available options allows you to integrate printing functionality into medical imaging applications, supporting clinical workflows that still rely on hard copy output. In the next tutorial in this series, I will cover DICOM Structured Reports for encoding clinical findings in a machine-readable format. See you then!