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

DICOM Print uses a three-level hierarchy:

DICOM Print — Three-Level Hierarchy saravanansubramanian.com Film Session groups Film Boxes; each Film Box is one sheet composed of Image Boxes Film Session the overall print job — one per print request Film Box 1 one printed sheet of film Film Box 2 · ... · Film Box N additional sheets in the session Image Box 1 position on film Image Box 2 position on film Image Box N last position each Image Box holds one image plus its position on the sheet

Key SOP Classes

Print Management uses several SOP Classes:

SOP ClassUIDPurpose
Basic Film Session1.2.840.10008.5.1.1.1Print job settings
Basic Film Box1.2.840.10008.5.1.1.2Film sheet settings
Basic Grayscale Image Box1.2.840.10008.5.1.1.4Grayscale image position
Basic Color Image Box1.2.840.10008.5.1.1.4.1Color image position
Printer SOP Class1.2.840.10008.5.1.1.16Printer status
Basic Grayscale Print Meta1.2.840.10008.5.1.1.9Meta SOP Class

Print Management uses N-DIMSE operations:

OperationPurpose
N-CREATECreate Film Session or Film Box
N-SETSet image data in Image Box
N-ACTIONTrigger print action
N-DELETEDelete session/box after printing
N-GETQuery 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:

FormatDescription
STANDARD\1,11 image per film
STANDARD\2,24 images (2x2 grid)
STANDARD\3,39 images (3x3 grid)
STANDARD\4,416 images (4x4 grid)
STANDARD\2,36 images (2 cols x 3 rows)
ROW\1,2,3Variable row layout (1+2+3 images)
COL\1,2,3Variable column layout

Film Size Options

Common film sizes supported by DICOM printers:

Size IDDimensions
8INX10IN8” x 10”
10INX12IN10” x 12”
10INX14IN10” x 14”
11INX14IN11” x 14”
14INX14IN14” x 14”
14INX17IN14” x 17”
24CMX30CM24cm x 30cm
A3, A4Standard paper sizes

Medium Types

Different media for different clinical needs:

MediumUse Case
PAPERPaper printouts
CLEAR FILMTransparent film
BLUE FILMBlue-tinted film (common)
MAMMO CLEAR FILMMammography clear film
MAMMO BLUE FILMMammography blue film

Film Orientation and Polarity

Additional display settings:

AttributeOptions
Film OrientationPORTRAIT, LANDSCAPE
PolarityNORMAL, REVERSE
Magnification TypeREPLICATE, BILINEAR, CUBIC, NONE
Border DensityBLACK, WHITE
Empty Image DensityBLACK, 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

Complete sequence for printing multiple images:

DICOM Print Association Call Flow saravanansubramanian.com SCU-driven print job: Session -> Box -> Images -> Print -> Cleanup Print SCU (workstation) initiates each N-service Print SCP (printer) manages SOP instances and hardware 1 N-CREATE Film Session returns Film Session SOP Instance UID 2 N-CREATE Film Box (references Session) SCP returns list of Image Box SOP Instance UIDs 3 N-SET Image Box (per image) populate each box with pixel data 4 N-ACTION on Film Box (Action Type ID = 1) triggers physical printing Repeat steps 2 through 4 for additional films in the session 5 N-DELETE Film Session release SCP-side resources

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!