# KPACS-neo **Repository Path**: coderfang/KPACS-neo ## Basic Information - **Project Name**: KPACS-neo - **Description**: https://github.com/andreasknopke/KPACS-neo - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-07-21 - **Last Updated**: 2026-07-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # K-PACS.neo A modern C# port of key components from **K-PACS**, the free DICOM workstation I originally wrote about 20 years ago. K-PACS was one of the first freely available DICOM viewers and became widely used in radiology departments, veterinary clinics, and research labs around the world. This project aims to bring the core DICOM infrastructure into the .NET ecosystem, built on top of [fo-dicom](https://github.com/fo-dicom/fo-dicom) and targeting **.NET 10**. The supported application shape in this repository is: - **K-PACS Viewer (Avalonia)** — the main workstation, including local mode, local GPU/OpenCL mode, and an integrated remote-render / remote-imagebox option - **K-PACS Render Server** — the companion headless service that provides remote rendering and remote study browsing for that integrated viewer mode The old **WPF viewer has been retired from this repository**. Active UI development now happens only in the **Avalonia** application. ## Project Structure ``` KPACS.DCMClasses/ — Core DICOM class library (.NET 10, fo-dicom 5.1.3) ├── DicomTypes.cs — Enumerations (content types, VR types, bit depths, …) ├── DicomTagConstants.cs — UID constants, private tag definitions, UID registry ├── DicomTagValue.cs — Tag value wrapper (group, element, VR, value, name) ├── DicomBaseObject.cs — Base class with notification support ├── DicomHeader.cs — Core DICOM dataset wrapper (read/write/navigate tags) ├── DicomFunctions.cs — Utility functions (date/time, UID generation, name parsing, …) ├── DicomImage.cs — DICOM image file handling and pixel data access ├── DicomDirectory.cs — DICOMDIR creation and reading ├── DicomPdf.cs — Encapsulated PDF DICOM objects ├── DicomSecondaryCapture.cs — Secondary Capture creation from raw pixel data ├── DicomStructuredReport.cs — Structured Report (SR) creation and content management ├── DicomPresentationState.cs — Grayscale Softcopy Presentation State (GSPS) ├── DicomNetworkClient.cs — DICOM networking (C-ECHO, C-FIND, C-MOVE, C-STORE, Worklist) ├── DicomNetworkThread.cs — Multi-study async network operations with progress └── Models/ ├── StudyInfo.cs — Study / Series / Image info classes ├── PrintConfig.cs — DICOM print configuration └── WorklistItem.cs — Modality worklist item KPACS.Viewer.Avalonia/ — Cross-platform study browser + DICOM viewer (.NET 10, Avalonia 11.3) ├── App.axaml / App.axaml.cs — Application entry point, imagebox bootstrap, Semi.Avalonia light theme ├── Program.cs — Avalonia desktop entry point ├── MainWindow.axaml / .cs — K-PACS-style study browser with Database / Network / Filesystem modes ├── StudyViewerWindow.axaml / .cs — Multi-viewport study viewer with thumbnails, custom layouts, linked synchronization, progressive remote loading, volume-aware slab navigation, toolbox workflows, and a floating 3D rendering workspace ├── ViewerTypes.cs — ColorScheme, ViewerTool, MouseWheelMode, and navigation/tool enumerations ├── Models/ │ ├── BackgroundJobModels.cs — Background import/send job states and metadata │ ├── ImageboxModels.cs — Browser, study, import, filesystem tree, and query models │ ├── NetworkModels.cs — Remote archive and network settings models │ └── ToastNotificationItem.cs — Transient in-window notification models ├── Controls/ │ └── DicomViewPanel.axaml / .cs— Core viewer control: zoom, pan, window/level, stack scrolling, DICOM bitmap overlays, color photometric handling, DVR/orbit support, tilt-plane interaction, and in-panel volume controls ├── Services/ │ ├── BackgroundJobService.cs — Central job tracking and per-job log files for import/send │ ├── ImageboxBootstrap.cs — Local imagebox path setup under LocalApplicationData │ ├── ImageboxRepository.cs — SQLite storage for studies, series, instances, and search │ ├── DicomImportService.cs — Metadata indexing plus queued/background import into local imagebox/SQLite │ ├── DicomFilesystemScanService.cs — Scan-only preview of filesystem/DICOMDIR studies │ ├── DicomStudyDeletionService.cs — Delete study from SQLite and stored files │ ├── DicomPseudonymizationService.cs — Pseudonymize imported studies in-place │ ├── DicomRemoteStudyBrowserService.cs — Remote C-FIND/C-MOVE/C-STORE integration with queued background send │ ├── NetworkSettingsService.cs — Persistent network-settings.json management │ ├── NiftiMaskConverter.cs — NIfTI-1 → SegmentationMask3D converter for plugin output │ ├── RemoteStudyRetrievalSession.cs — Progressive representative-image-first retrieval │ ├── StorageScpService.cs — Local Storage SCP receiver with import pipeline │ ├── VolumeLoaderService.cs — Series-to-volume loader for axial/coronal/sagittal reconstruction │ ├── VolumeRegistrationService.cs — Lightweight translation-based prior/cross-modality registration for linked navigation │ ├── ViewerStudyContext.cs — Study viewer input context │ └── WindowPlacementService.cs — Window geometry persistence ├── Plugins/ │ ├── PluginManager.cs — Central plugin registry: discovery, lifecycle, and remote plugin merging │ ├── PluginInstance.cs — Per-plugin bookkeeping: manifest, directory, state, handle │ ├── ProcessPluginHost.cs — Out-of-process plugin spawner (child process + gRPC port scanning) │ ├── GrpcPluginAdapter.cs — Bridges IPlugin/ISegmentationProvider/IImageProcessor/IDicomAnalyzer to gRPC │ ├── RemotePluginAdapter.cs — Thin-client adapter forwarding plugin calls to render server │ └── InProcessPluginLoader.cs — .NET plugin loader via isolated AssemblyLoadContext ├── Windows/ ├── NetworkInfoWindow.cs — Runtime network status dialog └── NetworkSettingsWindow.cs — Network configuration dialog └── Rendering/ ├── DicomPixelRenderer.cs — Pixel rendering engine (platform-independent) ├── ColorLut.cs — Color lookup tables (platform-independent) ├── SeriesVolume.cs — In-memory voxel volume model with patient-space geometry and trilinear sampling ├── VolumeRenderState.cs — DVR camera, shading, and light-state model ├── VolumeReslicer.cs — Orthogonal and oblique reslice/slab projection engine (MPR, MipPR, MinPR, MPVRT) ├── VolumeSlicePlane.cs — Shared oblique plane geometry for tilted volume navigation └── VolumeTransferFunction.cs — DVR transfer-function presets for CT/PET-style rendering KPACS.SDK/ — Zero-dependency plugin contract library (.NET 10) ├── IPlugin.cs — Core plugin interface: InitializeAsync, ShutdownAsync, lifecycle ├── PluginManifest.cs — Plugin identity, capabilities, runtime, and task catalogue ├── PluginCapability.cs — Flags enum: Segmentation, ImageProcessing, DicomAnalysis, DicomCommunication ├── PluginHostContext.cs — Host-provided context: scratch dir, data dir, version ├── PluginState.cs — Lifecycle states: Discovered → Starting → Ready → Busy → Faulted → Stopped ├── Contracts/ — Capability interfaces: ISegmentationProvider, IImageProcessor, IDicomAnalyzer, IDicomCommunicationHandler └── Models/ — Shared DTOs: SegmentationRequest/Result, SegmentedStructure, VolumeDescriptor, ProgressReport, etc. KPACS.SDK.Grpc/ — Language-agnostic gRPC bridge for out-of-process plugins (.NET 10) └── Protos/plugin_service.proto — PluginService: GetManifest, Initialize, Shutdown, RunSegmentation, ProcessImage, AnalyzeDicom KPACS.RenderServer.Protos/ — Shared gRPC contracts for remote rendering, study browsing, and plugin proxy └── Protos/ ├── render_service.proto — Session, volume, render, input, study-browser services └── plugin_proxy_service.proto — PluginProxyService: ListPlugins, GetSegmentationTasks, RunSegmentation, GetMaskData KPACS.RenderServer/ — Headless remote rendering and imagebox-backed study-browsing service (.NET 10) ├── Program.cs — ASP.NET Core/gRPC host entry point with PluginManager and PluginProxyService ├── appsettings.json — Default server URL, imagebox database, and plugin directory settings └── Services/ — Session lifecycle, volume loading, render orchestration, study-browser, and plugin proxy services Plugins/ — Reference plugin implementations └── KPACS.Plugin.TotalSegmentator/ — Python-based TotalSegmentator plugin (gRPC sidecar) ├── plugin.json — Plugin manifest declaring segmentation capabilities ├── server.py — gRPC server entry point (KPACS_PLUGIN_PORT protocol) ├── totalseg_bridge.py — TotalSegmentator integration bridge └── requirements.txt — Python dependencies VolumeRenderingPresetCatalog.cs — Catalog for DVR presets, shading presets, light directions, and recommended color maps ``` ## Current Status ### ✅ Completed: DCMClasses Core Library The entire **DCMClasses** package has been ported — this is the foundational DICOM data layer that everything else builds on. It covers: - **DICOM parsing & serialization** — reading/writing DICOM files, tag manipulation, sequence navigation, character set support - **DICOM networking** — full async C-ECHO, C-FIND (Patient/Study/Series/Image level), C-MOVE, C-STORE SCU, and Modality Worklist queries - **Image objects** — pixel data access, frame extraction, transfer syntax handling, compression/decompression - **Specialized SOP classes** — Secondary Capture, Encapsulated PDF, Structured Reports, Presentation State (GSPS with annotations, windowing, spatial transforms) - **DICOMDIR** — creation and reading of media directory structures - **Utility functions** — UID generation, date/time conversions, patient name parsing, age calculation ### ✅ Completed: Avalonia Study Browser + Viewer (Cross-Platform) The Avalonia application has moved beyond a single-file viewer and now includes a working **K-PACS-style local study browser** on top of the cross-platform viewer: - **Database mode** backed by a local SQLite imagebox - **Filesystem mode** with Windows-style `Computer` root, drive browsing, folder scan, and optional DICOMDIR usage - **Network mode** with configured remote archive search, preview of remote series, and representative-image-first retrieval into the local imagebox - **Preview-before-import workflow**: filesystem scans build preview studies first, and opening a study can copy it into the local imagebox in the background while it is already viewable - **Study actions**: view, send to remote archive, pseudonymize, and delete study (including multi-select send/delete for local studies) - **Background job monitor** for import/send tasks with progress, per-job logs, and optional DICOM communication trace inspection - **Multi-window study viewing** with configurable 1-4 viewer windows, persisted placement per viewer, cross-window linked navigation, and a safety-first clear-all-open-viewers flow before opening a new study - **Multi-viewport study viewer** with thumbnail strip, standard and custom layouts, double-click single-view focus toggle, LUT switching, stack-tool drag behavior, direct active-viewport selection, drag-reassignable series layouting, and cross-window series drag/drop with a floating drag preview that stays visible across viewer boundaries - **Patient-history comparison workflow** with automatic prior assignment to additional viewer windows, patient-level double-click loading across local repository plus remote archive results, and newest-to-oldest study distribution across comparison viewers/history - **Interactive orientation/navigation overlays** including patient left/right markers and a live 3D cursor for cross-view localization within the same viewer or across open viewers, available via `Shift` or the viewport toolbox and now also working with topograms/localizers that share the same frame of reference - **Expanded measurement toolkit** including pixel lens, line, angle, annotation, rectangle ROI, ellipse ROI, polygon ROI, erase, and modify/nudge workflows, all anchored to the referenced slice geometry in patient space - **ROI analytics panel** with floating histogram/distribution details, draggable labels, pin/collapse persistence, and modality-aware statistics such as CT HU summaries, MR intensity summaries, and slice-level radiomics-style percentiles and spread metrics - **Semi-automatic ROI outlining** for polygon and volumetric ROI workflows via double-click seed detection, followed by interactive grow/shrink sensitivity correction for fast lesion cleanup - **True multi-slice 3D ROI workflow** with slice-to-slice contour drafting, interpolation between source slices, rotatable mesh preview, persistent/pinnable 3D model panel, and additive multi-component capture so disconnected structures can remain separate within one saved ROI model - **Research measurement workflow** with viewport-accessible `Suggest RECIST follow-up`, patient-space lesion tracking metadata, slice radiomics extraction for ROI measurements, and archiveable research SR export with scene-state payload support - **Volume-aware series viewing** for real volumetric CT/MR stacks with cached in-memory voxel volumes, axial/coronal/sagittal reslicing, and slab projection modes - **In-panel volume interaction badges** shown only for true volume datasets: orientation switching, projection-mode switching, and drag-adjustable slab thickness in mm - **Floating 3D rendering workspace** with per-viewport projection mode selection, DVR transfer presets, shading presets, light-direction presets, and viewer-wide medical color maps - **Direct volume rendering (DVR)** with CPU ray casting, progressive fast/sharp rerendering, orbit interaction, and preset-driven shading/light behavior - **Oblique tilt-plane navigation** via a dedicated toolbox tool that tilts the current slice/slab plane in all volume modes, including DVR, while wheel and middle-drag continue front-to-back scrolling through the volume - **Parallelized volume reslicing/projection** for oblique slabs and thick orthogonal slabs to improve interactive performance on multi-core CPUs - **Linked slice synchronization** for same-space series plus lightweight prior-study / CT-MR fallback registration based on cached voxel volumes - **Integrated remote rendering mode** at the study-browser level with persisted render-server endpoint settings, remote imagebox browsing, transparent study open flow, and server-side rendering for both thin 2D series and full volume datasets - **Key-image workflow** with K-PACS-root Secondary Capture generation, volume-mode key-image toggling, and preview-strip marking only for K-PACS-managed key-image series - **DICOM rendering coverage** including bitmap overlay planes (60xx), embedded overlay bits, RGB Secondary Capture, and multiple YBR photometric interpretations - **Search/filter support** in Database, Filesystem, and Network mode, including wildcard remote matching and safe blocking of empty remote queries - **Local Storage SCP receiving** backed by fo-dicom with automatic import into the local imagebox - **Operational polish** including toast notifications, persisted browser/viewer window placement, persisted study browser splitters, and non-modal viewer windows - Shares the same platform-independent rendering engine and color LUTs across the current C# viewer stack - Uses Avalonia pointer events, StorageProvider dialogs, and Semi.Avalonia styling ### Screenshots #### Study Browser ![K-PACS.neo Avalonia Study Browser](Images/K-PACS%20Study%20Browser.png) #### Viewer / Workflow Detail ![K-PACS.neo Avalonia viewer workflow detail](Images/K-PACS%20Viewer%20with%203D%20ROI.png) ### ✅ Completed: Plugin SDK & AI Segmentation Architecture K-PACS.neo now includes a four-tier **Plugin SDK** that supports AI segmentation, image processing, DICOM analysis, and DICOM communication extensions: - **KPACS.SDK** — zero-dependency contract library that plugin authors reference; defines `IPlugin`, capability interfaces (`ISegmentationProvider`, `IImageProcessor`, `IDicomAnalyzer`, `IDicomCommunicationHandler`), manifests, and shared DTOs - **KPACS.SDK.Grpc** — language-agnostic gRPC bridge for out-of-process plugins (Python, Go, Rust, etc.) via a `PluginService` proto - **PluginManager** — central registry that discovers `plugin.json` manifests, manages plugin lifecycles (start/stop/fault), and provides convenience methods like `GetSegmentationProviderAsync` - **ProcessPluginHost** — spawns child processes for out-of-process plugins, scans stdout for `KPACS_PLUGIN_PORT=`, and manages the gRPC channel lifecycle - **GrpcPluginAdapter** — bridges `IPlugin` / `ISegmentationProvider` / `IImageProcessor` / `IDicomAnalyzer` to the gRPC `PluginService` for cross-language interop - **InProcessPluginLoader** — loads .NET plugin assemblies via isolated, collectible `AssemblyLoadContext` instances with per-plugin dependency resolution - **Thin-client plugin proxy** — a `PluginProxyService` gRPC service on the render server lets thin clients invoke server-side plugins without local Python, GPU drivers, or plugin processes; `RemotePluginAdapter` on the viewer side forwards all calls transparently - **NiftiMaskConverter** — converts NIfTI-1 segmentation output (binary or multilabel, `.nii`/`.nii.gz`) into packed-bit `SegmentationMask3D` objects for overlay rendering, centerline planning, and measurement workflows - **Anatomy workspace integration** — the "AI Segmentation" panel in the anatomy workspace lets users pick a plugin and task, run segmentation with live progress, and import results directly into the study's segmentation mask dictionary - **Reference plugin** — TotalSegmentator Python sidecar plugin with `plugin.json` manifest, gRPC server, and TotalSegmentator bridge ### 🔲 Still To Do The following major components from the original K-PACS have **not yet been ported**: | Component | Description | |---|---| | **Email Mode** | Import/export or mail-driven workflows | | **Query/Retrieve SCP** | Full server-side query/retrieve provider and broader service administration | | **Print** | DICOM Print SCU, print preview, film layout | | **Report Writer** | Structured report authoring and display | | **CD Burner** | DICOM media creation with auto-run viewer | | **RIS Interface** | Worklist-driven workflow integration | | **Advanced Annotations** | Text annotations, richer editing UX, and more parity with legacy drawing/report tools | | **Advanced Viewing** | Hanging protocols, lightbox tiling, cine playback, magnifier, and higher-level workflow presets | ## Technology | | | |---|---| | **Language** | C# 13 | | **Runtime** | .NET 10 | | **K-PACS DICOM classes** | Self-developed and ported K-PACS DICOM classes in `KPACS.DCMClasses`, serving as the legacy-port foundation and primary domain model layer | | **DICOM library** | [fo-dicom 5.1.3](https://github.com/fo-dicom/fo-dicom) | | **DICOM codecs** | [fo-dicom.Codecs 5.13.2](https://github.com/fo-dicom/fo-dicom) | | **SQLite** | [Microsoft.Data.Sqlite 9.0.3](https://www.nuget.org/packages/Microsoft.Data.Sqlite/) | | **Cross-platform Viewer** | [Avalonia 11.3.7](https://avaloniaui.net/) (Windows, Linux, macOS) | | **Avalonia Theme** | [Semi.Avalonia 11.3.7.3](https://www.nuget.org/packages/Semi.Avalonia/) | | **gRPC** | [Grpc.Net.Client 2.71.0](https://www.nuget.org/packages/Grpc.Net.Client/) / [Grpc.AspNetCore 2.71.0](https://www.nuget.org/packages/Grpc.AspNetCore/) / [Google.Protobuf 3.30.2](https://www.nuget.org/packages/Google.Protobuf/) | | **Plugin SDK** | KPACS.SDK (zero-dependency contracts) + KPACS.SDK.Grpc (cross-language bridge) | | **Original** | Written in Delphi (Object Pascal), ~150k lines of application code | ## Building ```bash # Core library dotnet build KPACS.DCMClasses/KPACS.DCMClasses.csproj # Plugin SDK (zero-dependency contracts) dotnet build KPACS.SDK/KPACS.SDK.csproj # Plugin SDK gRPC bridge dotnet build KPACS.SDK.Grpc/KPACS.SDK.Grpc.csproj # Cross-platform Avalonia viewer (includes plugin host) dotnet build KPACS.Viewer.Avalonia/KPACS.Viewer.Avalonia.csproj # Remote render server (includes plugin proxy) dotnet build KPACS.RenderServer/KPACS.RenderServer.csproj # Full solution dotnet build CSharp.sln ``` ## Release Packaging The repository includes a GitHub Actions workflow at [.github/workflows/release-packages.yml](.github/workflows/release-packages.yml) that builds four native self-contained release artifacts for the Avalonia viewer: - `win-x64` — single-file `.exe` packed as `.zip` - `linux-x64` — single-file executable packed as `.tar.gz` - `osx-x64` — zipped `KPACS-neo.app` bundle for Intel Macs - `osx-arm64` — zipped `KPACS-neo.app` bundle for Apple Silicon Macs These release builds use: - self-contained .NET 10 runtime - single-file publish - embedded native libraries via self-extraction - release symbols disabled for smaller artifacts - bundled neuro anatomy pack in `anatomy-packs/cranium-base.sample.json` ### Local publish commands These are the exact publish settings used for release packaging: ```bash dotnet publish KPACS.Viewer.Avalonia/KPACS.Viewer.Avalonia.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None -p:DebugSymbols=false dotnet publish KPACS.Viewer.Avalonia/KPACS.Viewer.Avalonia.csproj -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None -p:DebugSymbols=false dotnet publish KPACS.Viewer.Avalonia/KPACS.Viewer.Avalonia.csproj -c Release -r osx-x64 --self-contained true -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None -p:DebugSymbols=false dotnet publish KPACS.Viewer.Avalonia/KPACS.Viewer.Avalonia.csproj -c Release -r osx-arm64 --self-contained true -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None -p:DebugSymbols=false ``` ### GitHub Release flow - Create a tag such as `0.5.0` - Publish a GitHub Release for that tag - The workflow builds all three platform packages on native runners and attaches them to the release automatically You can also run the workflow manually with `workflow_dispatch` to generate test artifacts without publishing a release. ### macOS note The macOS package is emitted as an unsigned `.app` bundle. That is the most practical first-release shape for “download, unpack, start”, but Gatekeeper may still require the user to right-click the app and choose `Open` once unless the app is later code signed and notarized. ## Running ```bash # Avalonia viewer (any platform) dotnet run --project KPACS.Viewer.Avalonia/KPACS.Viewer.Avalonia.csproj # Render server dotnet run --project KPACS.RenderServer/KPACS.RenderServer.csproj ``` ## Avalonia Browser Workflow The Avalonia application now supports a practical local-plus-network K-PACS workflow: - **Database** — studies already imported into the local SQLite imagebox - **Filesystem** — browse drives/folders, scan DICOM folders or DICOMDIR media, preview studies, then import on demand - **Filesystem** — browse drives/folders, scan DICOM folders or DICOMDIR media, preview studies, open them immediately, and let the local copy continue in the background - **Network** — configure one primary remote archive, query studies, preview remote series, and open studies with progressive background retrieval into the local imagebox - **Email** — placeholder tab for future mail/export workflows ### Local imagebox The Avalonia application stores imported studies under the current user's local application data folder: ```text %LOCALAPPDATA%/KPACS.Viewer.Avalonia/Imagebox ``` This contains: - `imagebox.db` — SQLite metadata database - `Studies/` — imported DICOM files organized by Study Instance UID / Series Instance UID Additional runtime configuration files are stored alongside the imagebox root: - `network-settings.json` — local AE title/port plus the configured remote archive - `window-placement.json` — persisted browser/viewer geometry - `study-browser-layout.json` — persisted patient/study and study/series splitter sizes - `job-logs/` — per-job import/send logs written by the background job service ### Remote rendering mode The Avalonia viewer can also connect to a `KPACS.RenderServer` instance and use the same study-browser workflow against the server-side imagebox: - **Standalone CPU / local mode** — browser and viewer use the workstation's own imagebox and CPU rendering path - **Standalone local GPU/OpenCL mode** — browser stays local while volume rendering uses local OpenCL when available - **Remote render-server mode** — the browser can switch to the remote imagebox, and opened studies render through the server while preserving the normal K-PACS viewer workflow This remote mode is built into `KPACS.Viewer.Avalonia`; there is no separate thin-client application in the supported repository layout. ### Plugin architecture K-PACS.neo supports extensible AI and analysis plugins through a four-capability SDK: - **Segmentation** — whole-body or region-specific structure segmentation (e.g. TotalSegmentator) - **ImageProcessing** — image enhancement, filtering, and transformation operations - **DicomAnalysis** — automated DICOM dataset analysis and quality checks - **DicomCommunication** — custom DICOM networking workflows Plugins are discovered from `plugin.json` manifests in the `Plugins/` directory next to the viewer or render server executable. They can run: - **Out-of-process** — Python, Go, Rust, or any language implementing the gRPC `PluginService` protocol. The host spawns the child process and connects via gRPC. - **In-process** — .NET assemblies loaded via isolated `AssemblyLoadContext` with per-plugin dependency resolution and collectible unloading. - **Remote** — in thin-client mode, the viewer queries the render server's `PluginProxyService` for server-side plugins and forwards all execution transparently. No local Python, GPU drivers, or plugin binaries are needed on the thin client. ### Network workflow notes - Double-clicking a network study loads remote series metadata first, then opens the viewer as soon as the first representative images arrive. - Remaining series continue downloading in the background through the configured local Storage SCP. - Local studies can be sent back to the configured archive with the `Send` action in Database mode. - Empty network searches are blocked on purpose to avoid accidental full-archive C-FIND requests. ### Volume viewing notes - Volume controls are shown only when a series could be promoted to a true in-memory volume; 2D datasets such as plain radiography, angiography, or ultrasound continue to use the legacy single-slice viewer path. - The viewer loads the initial series through the existing file-based path first and upgrades matching series to cached voxel volumes in the background. - The orientation badge inside the view panel switches between Axial, Coronal, and Sagittal. - The projection badge inside the view panel switches between MPR, MipPR, MinPR, MPVRT, and DVR. - Dragging on the projection badge changes slab thickness in millimeters; holding Shift while dragging enables finer adjustment. - The viewport toolbox now includes a `Tilt plane` tool for oblique slice/slab navigation; left drag tilts the plane, while mouse wheel and middle-drag still move the tilted plane front-to-back through the dataset. - Oblique plane rendering shares the same patient-space slice model across MPR, MIP, MinIP, MPVRT, and DVR, so tilted navigation stays spatially consistent across all volume modes. - The 3D Rendering workspace exposes transfer-function presets such as Bone, Soft Tissue, Lung, Vascular Red, Skin Surface, Endoscopy, PET Hot Iron, PET Spectrum, and Perfusion, plus matching shading and light-direction presets. - Available medical color maps now include Grayscale, Inverted, Hot Iron, PET, Rainbow, Spectrum, Gold, Bone, Jet, BlackBody, and Flow. - Linked navigation continues to use exact patient-space matching for compatible series and can fall back to a lightweight translation-only volume registration for prior studies or cross-modality comparisons when both sides have volumes. - Open viewer windows for the same patient can broadcast linked navigation and Shift-based 3D cursor updates across monitors. ### Research workflow notes - Use the viewport toolbox or the measurement popup action `Suggest RECIST follow-up` after selecting a baseline line or ROI measurement. - RECIST suggestions use the selected baseline measurement as the source lesion and the active or toolbox-target viewport as the follow-up target series. - Suggested follow-up measurements retain tracking metadata such as label, timepoint, confidence summary, and patient-space lesion center. - ROI-based measurements can also feed slice radiomics extraction and research SR export payloads for downstream review or archival. ### ROI workflow notes - Rectangle, ellipse, and polygon ROIs now expose richer per-slice measurement summaries, including mean, median, standard deviation, percentile bands, min/max, and physical area. - Selecting an ROI opens a floating histogram/details panel with draggable positioning, pinning, collapse/expand support, and modality-specific supplemental hints such as CT attenuation language or MR/DWI context. - Polygon ROI supports double-click auto-outline when no line has been started; use the ROI panel `Shrink` and `Grow` actions to tune the segmentation sensitivity after creation. - The `Modify` tool supports keyboard nudging of the selected measurement with the arrow keys; hold `Shift` for larger steps. ### 3D ROI workflow notes - Choose `3D ROI` from the viewport toolbox to draft a volumetric ROI across slices; double-click without a line to auto-outline the pointed structure, or double-click with a line already started to close the current contour. - The floating 3D ROI panel shows a rotatable mesh preview, estimated volume, and source/interpolated contours; use the arrow keys to rotate the preview and `Enter` / `Esc` to finish or cancel the draft. - `Shrink` and `Grow` re-run the latest auto-outline with lower or higher sensitivity while preserving the current preview orientation. - `Add` appends another disconnected component into the same 3D ROI draft instead of replacing the existing structure, which is useful for paired anatomy such as left/right ventricles or bilateral lesions. - Saved 3D ROI measurements continue to show interpolated contours during slice navigation while keeping source slices visually distinguishable from generated intermediate slices. ### Viewer interaction notes - The layout popup supports both standard grids and custom row-based layouts such as `2:3` or `1,2`. - Double-clicking a viewport toggles between the current layout and a focused single-view mode. - Key-image preview badges are reserved for K-PACS-managed Secondary Capture series generated under the K-PACS UID root. - Bitmap overlays from 60xx groups are rendered directly in the panel, with fallback extraction from embedded overlay bits when needed. ### Remote DICOM archive configuration examples The Avalonia browser currently stores network configuration in `network-settings.json` under `%LOCALAPPDATA%/KPACS.Viewer.Avalonia`. Example structure: ```json { "LocalAeTitle": "KPACS", "LocalPort": 11112, "InboxDirectory": "C:\\Users\\\\AppData\\Local\\KPACS.Viewer.Avalonia\\network-inbox", "SelectedArchiveId": "conquest-local", "Archives": [ { "Id": "conquest-local", "Name": "Local Conquest", "Host": "127.0.0.1", "Port": 5678, "RemoteAeTitle": "CONQUESTSRV1" } ] } ``` #### Conquest PACS example Use this when Conquest is running locally or on a reachable server and accepts query/retrieve on its configured TCP port. ```json { "LocalAeTitle": "KPACS", "LocalPort": 11112, "InboxDirectory": "C:\\Users\\\\AppData\\Local\\KPACS.Viewer.Avalonia\\network-inbox", "SelectedArchiveId": "conquest-main", "Archives": [ { "Id": "conquest-main", "Name": "Conquest Main", "Host": "192.168.1.50", "Port": 5678, "RemoteAeTitle": "CONQUESTSRV1" } ] } ``` Typical Conquest pairing: - Local Storage SCP in K-PACS: AE `KPACS`, port `11112` - Remote archive in K-PACS: host `192.168.1.50`, port `5678`, remote AE `CONQUESTSRV1` - Matching destination configured in Conquest for C-MOVE/C-STORE back to K-PACS: AE `KPACS` at your workstation IP and port `11112` #### Orthanc example Orthanc often uses AE title `ORTHANC` and DICOM port `4242` unless changed in its configuration. ```json { "LocalAeTitle": "KPACS", "LocalPort": 11112, "InboxDirectory": "C:\\Users\\\\AppData\\Local\\KPACS.Viewer.Avalonia\\network-inbox", "SelectedArchiveId": "orthanc-dev", "Archives": [ { "Id": "orthanc-dev", "Name": "Orthanc Dev", "Host": "127.0.0.1", "Port": 4242, "RemoteAeTitle": "ORTHANC" } ] } ``` Checklist for any remote PACS: - The remote PACS must know the workstation as destination AE `KPACS` on port `11112` (or whatever you configure locally). - Firewalls must allow inbound traffic to the local Storage SCP port. - AE titles must match exactly, including case and truncation to the DICOM 16-character limit. - If C-FIND works but retrieve fails, the first thing to check is usually the remote PACS destination table for the local AE. ### Current viewer capabilities - Window/level, zoom, pan, fit-to-window, and color LUT switching - Stack tool with accelerated drag scrolling for series browsing - Click-to-activate viewports inside the study viewer - Thumbnail strip for jumping between series and drag-dropping series into arbitrary viewports - Patient orientation markers on the viewer overlay for left/right validation - Shift-held 3D cursor that projects the hovered location into compatible views without locking the viewer in localization mode - Measurement mode selector with editable line, angle, rectangular ROI, polygon ROI, and pixel lens tools - Measurement objects persist against the correct image geometry and are reprojected only onto compatible slices/views from the same acquisition space - Series overview panel in the browser with persisted splitter sizing - Progressive remote retrieval support inside the viewer, including status updates while images arrive - Pseudonymization of imported studies - Delete-study workflow that removes both database rows and stored files - Send-to-archive workflow for local studies ## Background K-PACS was created around 2004 as a free DICOM workstation. It provided a full-featured PACS client including DICOM storage, query/retrieve, viewing, printing, CD burning, and modality worklist — capabilities that were typically only available in expensive commercial products at the time. It gained significant adoption worldwide, particularly in smaller imaging facilities and educational settings. **K-PACS.neo** preserves the architectural concepts of the original while modernizing the codebase for the .NET platform with cross-platform support via Avalonia. ## License This project is licensed under the [MIT License](LICENSE).