Cross-platform desktop application for exporting DICOM images to standard image formats.
- Python 3.10+ (3.12 recommended)
- Node.js 18+ (20 LTS recommended)
- Windows (tested), macOS or Linux
Use the provided startup scripts to run both frontend and backend automatically:
Windows:
.\start.ps1Linux/Mac:
chmod +x start.sh
./start.shThe scripts will launch both services in separate windows/processes.
# Navigate to backend folder
cd backend
# Create virtual environment
python -m venv venv
# Activate virtual environment
# Windows PowerShell:
.\venv\Scripts\activate
# Windows CMD:
venv\Scripts\activate.bat
# macOS/Linux:
source venv/bin/activate
# Install dependencies
# For Windows (no C compiler needed):
pip install -r requirements-minimal.txt
# For macOS/Linux:
pip install -r requirements.txt
# Start the backend server
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000Expected output:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process
INFO: Started server process
INFO: Waiting for application startup.
INFO: Application startup complete.
The backend will be available at http://127.0.0.1:8000
In a new terminal:
# Navigate to frontend folder
cd frontend
# Install dependencies
npm install
# Start the development server
npm run devExpected output:
> dicom-image-exporter@0.1.0 dev
> concurrently "npm run dev:react" "npm run dev:electron"
[0] VITE v5.0.11 ready in 234 ms
[0] ➜ Local: http://localhost:5173/
[1] Waiting for http://localhost:5173...
[1] Electron started
The Electron app will launch automatically and connect to both the Vite dev server (port 5173) and the Python backend (port 8000).
- Scanner Page - Click "Browse" to select a folder containing DICOM files
- Preview Page - Review discovered series, select which ones to export
- Export Page - Configure output settings and click "Start Export"
Results are saved in your chosen output directory:
output_directory/
└── {StudyUID}/
└── {SeriesUID}/
├── 0001.png
├── 0002.png
└── ...
- 🔍 Scan & Browse - Recursively scan local DICOM folders (with optional ZIP support)
- 👁️ Preview Series - View DICOM series metadata and thumbnails in table or grid view
- 🎨 Smart Processing - Apply DICOM windowing (VOI LUT, Window Level/Width)
- 📤 Multi-Format Export - Export to PNG, JPEG, TIFF, JFIF, or WebP
- ✅ Image Validation - Enforce platform constraints (32–20,000px, ≤4.7GB)
- 🎞️ Multi-frame Support - Automatically split multi-frame DICOMs into separate images
- 🎯 Frame Limiting - Export all frames or limit to first N frames per series
- 📊 Progress Tracking - Real-time export progress with live statistics
- ⏸️ Cancel Jobs - Gracefully stop export jobs in progress
- 📝 Export History - Track all exports with detailed status information
┌─────────────────────────────────────┐
│ ELECTRON DESKTOP APP │
│ ┌───────────────────────────────┐ │
│ │ React Frontend (Vite) │ │
│ │ • Scanner Page │ │
│ │ • Preview Page (Grid/Table) │ │
│ │ • Export Page │ │
│ └───────────┬───────────────────┘ │
│ │ HTTP (port 5173) │
└──────────────┼──────────────────────┘
│
│ Axios REST API
│ (localhost:8000)
▼
┌─────────────────────────────────────┐
│ PYTHON FASTAPI BACKEND │
│ ┌───────────────────────────────┐ │
│ │ FastAPI Endpoints │ │
│ │ • /api/scan │ │
│ │ • /api/export/start │ │
│ │ • /api/export/status │ │
│ │ • /api/thumbnail │ │
│ └───────────┬───────────────────┘ │
│ │ │
│ ┌───────────▼───────────────────┐ │
│ │ DICOM Processing │ │
│ │ • pydicom (read files) │ │
│ │ • pylibjpeg (decompress) │ │
│ │ • Pillow (convert/export) │ │
│ └───────────────────────────────┘ │
│ │ │
│ ▼ │
│ File System │
└─────────────────────────────────────┘
Frontend:
- Electron 28.x, React 18.x, TypeScript, Vite 5.x, Zustand 4.x, Axios
Backend:
- FastAPI 0.109, pydicom 2.4, pylibjpeg, Pillow 10.x, NumPy 1.26, Uvicorn
Communication:
- REST API over HTTP (localhost:8000)
- Background task processing
- Real-time progress polling (500ms intervals)
- PNG - Lossless, best quality, larger files
- JPEG - Lossy, smaller files, quality 1-100
- TIFF - Lossless or compressed, supports 16-bit
- WebP - Modern format, good compression
Images are validated and processed to meet common platform requirements:
- Minimum dimensions: 32×32 pixels
- Maximum dimensions: 20,000×20,000 pixels
- Maximum file size: 4.7 GB
- Images outside min/max are skipped or auto-downscaled
- Multi-frame DICOMs split into individual images
- VOI LUT - Value of Interest Look-Up Table applied if present
- Window Level/Width - Adjusts contrast for viewing
- Modality LUT - Converts stored values to meaningful units
- Color spaces - Handles RGB, YBR_FULL, PALETTE COLOR
- Bit depths - Supports 8-bit and 16-bit output
Control how many frames to export per series:
- Export all frames - Export every frame from every series
- Limit to first N frames - Quick presets for 5, 10, 25, 50 frames
- Custom limit - Set any number from 1-1000 frames per series
Useful for:
- Quick previews (first 5 frames)
- Dataset sampling (first 25 frames)
- Testing workflows before full export
- Parallel processing - Uses ThreadPoolExecutor (4 workers)
- Background jobs - Exports run asynchronously
- Progress tracking - Real-time updates every 500ms
- Multi-frame optimization - Efficiently handles large datasets
Typical performance:
- Single-frame DICOM: ~0.1-0.3 sec/image
- Multi-frame (60+ frames): ~0.2-0.5 sec/frame
- Frontend has 10-minute polling timeout for long exports
- Large multi-frame DICOMs may use significant RAM
- Some older JPEG/JPEG-LS formats require additional packages
- ZIP files are detected but not auto-extracted (future feature)
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
MIT License - see LICENSE file for details