DICOM Plugin

View medical images with DicomPlugin

The DICOM plugin adds medical-image viewing to Doconut: multi-frame DICOM files render as an animated overview, individual frames, or both. DICOM is a plugin-only format — without this plugin (and its license capability), .dcm files cannot be opened at all.

SurfaceUse it when
Viewer with DicomConfig (C#)You open DICOM files on the server and choose how their frames are presented
The viewer (docViewer)You show the study in your page: animation and frames

The plugin has no widget of its own: DICOM files open in the regular viewer. With the Converter plugin also registered, .dcm and .ima files can be converted to Pdf, Png, Jpeg, Bmp, Tiff or Gif; that conversion needs the Dicom capability as well.

Install the package

bash
dotnet add package Doconut.NETStandard.Dicom

The unversioned command installs the latest stable release. To pin the plugin to the release this documentation describes, pass the version separately:

bash
dotnet add package Doconut.NETStandard.Dicom --version 26.10.0

Keep the DICOM package at the same version as Doconut.NETStandard. The package ID is Doconut.NETStandard.Dicom; .<version> appears only in the downloaded .nupkg filename.

The plugin's license file, Doconut.Viewer.Dicom.lic, goes in the same folder as Doconut.Viewer.lic; it is read together with the viewer license.

Register the plugin

csharp
builder.Services.AddDoconut(options =>
{
    options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});

The plugin (Name: "Doconut DICOM Viewer") registers viewers for the .dcm and .ima extensions, gated by the Dicom capability. Without a license that grants it, AddDoconut() throws an InvalidOperationException at startup, before the app serves a request:

text
The Dicom plugin is registered via AddPlugin but no active license grants Dicom. Remove the AddPlugin<...>() call or install a license (or trial/demo) that includes Dicom.

It throws for no license, a legacy TRIAL file, a license without Dicom, and a paid license used outside its version window. Temporary Demo/NFR licenses are accepted. See License Setup for how licenses are loaded.

Because no built-in viewer handles these formats, the runtime gate also fails hard if the capability later becomes unavailable:

text
LicenseException: This document type requires the 'Dicom' plugin license.

Licensing & watermark

License stateStartupDICOM output
Paid license granting Dicom, within its version windowStartsRendered under the normal page watermark rules
Active Temporary (Demo/NFR) licenseStartsRendered with the evaluation watermark
No license, a legacy TRIAL file, a license without Dicom, or a paid license outside its version windowAddDoconut() throws—

The normal page watermark decision also applies to DICOM output. For animated output, each GIF frame is stamped so the mark remains visible throughout playback. A custom DocOptions.Watermark is used only when the license path permits custom watermarks; it cannot replace an evaluation watermark.

Use from C#

csharp
var token = await viewer.OpenDocumentAsync(path, new DicomConfig
{
    DisplayMode = DicomDisplayMode.AnimationAndFrames
});

Viewer.GetDicomMetadataAsync(token) exists on this package, but it returns null for a DICOM session: see Framework notes.

Display modes, resolution and metadata

Display modes

Multi-frame DICOM files can be presented three ways (DicomDisplayMode):

ModePages producedUse for
AnimationOnlyPage 1 = animated GIF looping all framesQuick cinematic review
FramesOnlyPages 1..N = one static PNG per frameFrame-by-frame diagnostic navigation
AnimationAndFrames (default)Page 1 = animated GIF, pages 2..N+1 = one static PNG per frame (N = frame count)Overview + detail in one document

Animation timing is controlled by AnimationFrameDelayMs (default 100 ms = 10 FPS; GIF granularity is 10 ms units) and LoopCount (0 = loop forever).

Resolution

DicomConfig renders at 100 DPI per axis by default. The resolution properties have a fallback chain worth knowing: if you don't set HorizontalResolution/VerticalResolution explicitly, they follow BaseConfig.ImageResolution when that is configured, and only then fall back to 100.

csharp
// Uniform bump via the base property…
new DicomConfig { ImageResolution = 150 };

// …or per-axis control
new DicomConfig { HorizontalResolution = 200, VerticalResolution = 150 };

Metadata

DicomMetadata carries technical and imaging tags only — frame count, dimensions, bit depth, photometric interpretation, transfer syntax, modality and the default window level. It contains no patient-identifiable data. The full list is in the API reference. On this package the metadata is not available; see Framework notes.

In the viewer

The viewer needs no DICOM-specific setup. When the open document is a DICOM file, it requests the metadata (?token=<token>&meta=1) and adds a DICOM button that opens a technical-properties panel. If that request fails, the panel stays hidden and the document still renders. On this package the request answers 501, so the panel never appears.

Build your own frontend

The metadata is available over HTTP under the path where UseDoconut() is mounted (normally /doconut), for any open document token:

RoutePurposeSuccess response
GET ?token=<token>&meta=1Read the technical metadata of an open DICOM document200 — DicomMetadata as JSON, with the property names of the API reference (Width, Height, NumberOfFrames, …)
StatusWhenBody
404The document is not a DICOM filestatus only
501The document is a DICOM file, but this package cannot read its tags{ "error": "dicom_metadata_unsupported", "message": "DICOM technical metadata is not supported on this package: the underlying medical-imaging engine has no build for this target framework. On this package it always returns null; use the .NET 8 package if you need it. DICOM rendering is unaffected." }
500Reading the metadata failed{ "error": "metadata failed" }

Page images, including the animated first page, use the standard viewer image route.

In production

Multiframe studies can generate both an animation and one static page per frame. AnimationAndFrames provides the richest navigation but also has the highest rendering and cache cost. For large studies:

  • use FramesOnly when frame inspection matters more than cinematic playback;
  • avoid increasing both resolution axes without measuring memory;
  • close the session explicitly when the study is no longer open;
  • keep CachePages enabled only when repeat access benefits outweigh the retained images.

Put Doconut.Viewer.Dicom.lic next to Doconut.Viewer.lic on every server.

API reference

DicomConfig, DicomDisplayMode and DicomMetadata are in the Doconut namespace. DicomPlugin is in Doconut.Plugins.Dicom. The complete DicomConfig property table lives in Format Configs.

DicomConfig

csharp
public sealed class DicomConfig : BaseConfig
{
    public int HorizontalResolution { get; set; }   // default: ImageResolution when set, else 100
    public int VerticalResolution { get; set; }     // default: ImageResolution when set, else 100
    public int AnimationFrameDelayMs { get; set; } = 100;
    public ushort LoopCount { get; set; } = 0;      // 0 = loop forever
    public DicomDisplayMode DisplayMode { get; set; } = DicomDisplayMode.AnimationAndFrames;
}

DicomDisplayMode

csharp
public enum DicomDisplayMode { AnimationOnly, FramesOnly, AnimationAndFrames }

Viewer.GetDicomMetadataAsync

csharp
public Task<DicomMetadata?> GetDicomMetadataAsync(string token, CancellationToken ct = default);

Returns null when the document is not a DICOM file, and always returns null on this package. Throws InvalidOperationException when the token is unknown or expired.

DicomMetadata

csharp
public sealed class DicomMetadata
{
    public int Width { get; init; }
    public int Height { get; init; }
    public int NumberOfFrames { get; init; }
    public int BitsAllocated { get; init; }
    public int BitsStored { get; init; }
    public int SamplesPerPixel { get; init; }
    public string? PhotometricInterpretation { get; init; }
    public string? PixelRepresentation { get; init; }   // "Unsigned" or "Signed"
    public string? PlanarConfiguration { get; init; }
    public string? TransferSyntax { get; init; }
    public string? Modality { get; init; }              // null when not exposed
    public double? WindowCenter { get; init; }
    public double? WindowWidth { get; init; }
    public bool IsColor { get; init; }
}

Troubleshooting

SymptomCauseFix
AddDoconut() throws The Dicom plugin is registered via AddPlugin but no active license grants Dicom.No license, a TRIAL file, a license without Dicom, or a paid license outside its version windowInstall a license that grants Dicom, or remove AddPlugin<DicomPlugin>()
Opening a .dcm file throws Document format '.dcm' is not supported.DicomPlugin is not registered, or its package is not deployedAdd AddPlugin<DicomPlugin>() inside AddDoconut() and deploy the package
Opening a .dcm file throws LicenseException: This document type requires the 'Dicom' plugin license.The loaded license no longer grants DicomInstall a license that grants Dicom
Only one page appearsThe source is single-frame, or DisplayMode is AnimationOnlyUse FramesOnly or AnimationAndFrames for a multi-frame source
Animation is too fast or slowAnimationFrameDelayMs is off; effective GIF timing uses 10 ms unitsAdjust AnimationFrameDelayMs
Memory grows on large multiframe filesDisplay mode, resolution and page cache all add retained imagesSee In production; close sessions explicitly
Metadata is nullThe document is not a DICOM fileCheck the file type before asking for metadata
Metadata is null for a DICOM file, or &meta returns 501Expected limitation of this package; rendering is unaffectedUse the .NET 8 package when you need the tags
GetDicomMetadataAsync throws Document session not found. Please re-open document.The token expired or was never openedOpen the document again

Framework notes

  • No DICOM metadata. DICOM page rendering, individual frames, animation, transforms, and watermarking are supported. Technical tag metadata is not available in the .NET Standard package because the metadata reader ships only a .NET 8 build. Viewer.GetDicomMetadataAsync(token) therefore returns null for a DICOM session and logs a one-time warning. The corresponding ?token=…&meta=1 request returns HTTP 501 Not Implemented with the stable error code dicom_metadata_unsupported. Use the .NET 8 package when technical DICOM metadata is a requirement.
  • Windows only, like the rest of the .NET Standard package.

Was this page helpful?