<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>SmartPACS Lite - Free DICOM Viewer</title> <style> body font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #1e2a2e; color: #eee; .container max-width: 1400px; margin: auto; h1 margin: 0 0 5px; font-weight: 400; .sub color: #aaa; margin-bottom: 20px; border-left: 3px solid #2ecc71; padding-left: 15px; .toolbar background: #0f1720; padding: 12px 20px; border-radius: 30px; display: flex; gap: 15px; flex-wrap: wrap; margin-bottom: 20px; align-items: center; box-shadow: 0 4px 10px rgba(0,0,0,0.3); button background: #2c3e44; border: none; color: white; padding: 8px 20px; border-radius: 40px; cursor: pointer; font-size: 14px; transition: 0.2s; button.active background: #2ecc71; color: #000; font-weight: bold; button:hover background: #3e5a62; .dropzone border: 2px dashed #5a7c85; border-radius: 20px; padding: 20px; text-align: center; background: #0f1a1f; margin-bottom: 20px; cursor: pointer; .dropzone.drag-over border-color: #2ecc71; background: #1e3a2f; #viewerContainer background: #000; border-radius: 16px; overflow: hidden; box-shadow: 0 10px 25px rgba(0,0,0,0.5); position: relative; aspect-ratio: 16 / 13; min-height: 500px; .cornerstone-element width: 100%; height: 100%; display: block; .info margin-top: 15px; font-size: 14px; background: #0f1720; padding: 12px; border-radius: 12px; font-family: monospace; footer text-align: center; margin-top: 30px; font-size: 12px; color: #5f7f8c; @media (max-width: 700px) .toolbar button padding: 6px 12px; font-size: 12px; </style> </head> <body> <div class="container"> <h1>📷 SmartPACS Image Viewer <span style="font-size: 18px; background: #2ecc7122; padding: 2px 8px; border-radius: 20px;">FREE</span></h1> <div class="sub">Open-source DICOM viewer | Drag & drop DICOM files | Zoom/Pan/WL</div><div class="toolbar"> <span style="font-size:13px; margin-right:5px;">🔧 Tools:</span> <button id="btnZoom" class="active">🔍 Zoom/Pan</button> <button id="btnWwwc">🎚️ Window/Level</button> <button id="btnReset">⟳ Reset View</button> <span style="flex:1"></span> <span id="fileStatus" style="font-size:12px; color:#aaf0d0;">📄 No file loaded</span> </div>
<div id="dropzone" class="dropzone"> 💾 Drop DICOM file (.dcm) here or click to select<br> <small>Supports single-frame, grayscale DICOM (CT, MR, CR, DX)</small> </div> <input type="file" id="fileInput" accept=".dcm,.dic" style="display:none" />
<div id="viewerContainer"> <div id="dicomViewer" class="cornerstone-element"></div> </div> <div class="info" id="infoPanel"> <span>⚙️ Ready — Load a DICOM image to start.</span> </div> <footer> Using CornerstoneJS + WADO Image Loader | For educational / research use only. <br> Not a certified medical device. Always verify with original PACS. </footer> </div>
<!-- Load required libraries --> <script src="https://unpkg.com/cornerstone-core@2.6.1/dist/cornerstone.min.js"></script> <script src="https://unpkg.com/cornerstone-tools@6.0.5/dist/cornerstone-tools.min.js"></script> <script src="https://unpkg.com/cornerstone-wado-image-loader@4.3.1/dist/cornerstoneWADOImageLoader.bundle.min.js"></script> <!-- DICOM parser for file reading --> <script src="https://unpkg.com/dicom-parser@1.8.9/dist/dicomParser.min.js"></script>
<script> // ======================== Setup Cornerstone & Tools ======================== const element = document.getElementById('dicomViewer'); cornerstoneTools.init( globalToolSyncEnabled: true ); cornerstoneTools.external.cornerstone = cornerstone; cornerstoneTools.external.cornerstoneMath = null; // not needed for basic cornerstoneTools.external.Hammer = null;
// Define tools const ZoomTool = cornerstoneTools.ZoomTool; const PanTool = cornerstoneTools.PanTool; const WwwcTool = cornerstoneTools.WwwcTool;
cornerstoneTools.addTool(ZoomTool); cornerstoneTools.addTool(PanTool); cornerstoneTools.addTool(WwwcTool); smartpacs image viewer free
// Activate Zoom/Pan by default let activeTool = 'Zoom'; cornerstoneTools.setToolActive('Zoom', mouseButtonMask: 1 ); cornerstoneTools.setToolActive('Pan', mouseButtonMask: 1 ); // zooms with left click, pan with middle? Better: disable Pan initially // Actually correct: Let's set pan to not active, but we'll manage. cornerstoneTools.setToolActive('Pan', mouseButtonMask: 4 ); // middle mouse button pan cornerstoneTools.setToolActive('Wwwc', mouseButtonMask: 1 ); // will be activated later if needed. // Deactivate wwwc initially cornerstoneTools.setToolDisabled('Wwwc'); // But keep zoom fully active as left button cornerstoneTools.setToolActive('Zoom', mouseButtonMask: 1 );
// UI toggle function setActiveTool(toolName) // Disable all tools for left click usage cornerstoneTools.setToolDisabled('Zoom'); cornerstoneTools.setToolDisabled('Pan'); cornerstoneTools.setToolDisabled('Wwwc');
if (toolName === 'Zoom') cornerstoneTools.setToolActive('Zoom', mouseButtonMask: 1 ); activeTool = 'Zoom'; else if (toolName === 'Pan') cornerstoneTools.setToolActive('Pan', mouseButtonMask: 1 ); activeTool = 'Pan'; else if (toolName === 'Wwwc') cornerstoneTools.setToolActive('Wwwc', mouseButtonMask: 1 ); activeTool = 'Wwwc'; // update button styles document.getElementById('btnZoom').classList.toggle('active', toolName === 'Zoom'); document.getElementById('btnWwwc').classList.toggle('active', toolName === 'Wwwc'); // Pan stays without active look but we keep. document.getElementById('btnZoom').classList.toggle('active', toolName === 'Zoom'); document.getElementById('btnWwwc').classList.toggle('active', toolName === 'Wwwc');document.getElementById('btnZoom').addEventListener('click', () => setActiveTool('Zoom')); document.getElementById('btnWwwc').addEventListener('click', () => setActiveTool('Wwwc')); document.getElementById('btnReset').addEventListener('click', () => if (cornerstone.getEnabledElements().length > 0) const viewport = cornerstone.getViewport(element); viewport.scale = 1; viewport.translation = x: 0, y: 0 ; cornerstone.setViewport(element, viewport); document.getElementById('infoPanel').innerHTML = '<span>🔄 View reset to default.</span>'; );
// Enable the element cornerstone.enable(element); // Optional: resize handler window.addEventListener('resize', () => cornerstone.resize(element, true); );
// ======================== Load DICOM from File ======================== const dropZone = document.getElementById('dropzone'); const fileInput = document.getElementById('fileInput'); document
function loadDicomFromFile(file) if (!file) return; const fileReader = new FileReader(); fileReader.onload = function(e) const arrayBuffer = e.target.result; // Use cornerstoneWADOImageLoader to create imageId from raw buffer const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(arrayBuffer); // Load and display cornerstone.loadImage(imageId).then(image => cornerstone.displayImage(element, image); // Reset viewport const viewport = cornerstone.getViewport(element); viewport.scale = 1; viewport.translation = x: 0, y: 0 ; cornerstone.setViewport(element, viewport);
// Show basic metadata try Modality: $modality catch(e) document.getElementById('infoPanel').innerHTML = `<span>✅ Loaded: $file.name (metadata parsing limited)</span>`; ).catch(err => console.error(err); document.getElementById('infoPanel').innerHTML = `<span style="color:#ffaa88">❌ Failed to load DICOM: $err.message </span>`; ); ; fileReader.readAsArrayBuffer(file);// Drag & Drop handlers dropZone.addEventListener('dragover', (e) => e.preventDefault(); dropZone.classList.add('drag-over'); ); dropZone.addEventListener('dragleave', () => dropZone.classList.remove('drag-over'); ); dropZone.addEventListener('drop', (e) => e.preventDefault(); dropZone.classList.remove('drag-over'); const files = e.dataTransfer.files; if (files.length > 0 && (files[0].name.endsWith('.dcm') ); dropZone.addEventListener('click', () => fileInput.click(); ); fileInput.addEventListener('change', (e) => if (e.target.files.length > 0) loadDicomFromFile(e.target.files[0]); );
// Demo: Load a public sample DICOM from GitHub (a small CT slice) on page load to showcase viewer const sampleUrl = "https://raw.githubusercontent.com/OHIF/Viewers/master/extensions/dicom-dicomweb-viewer/test/fixtures/DICOM/CR-MONO1-10-chest.dcm"; fetch(sampleUrl).then(res => res.arrayBuffer()).then(buffer => const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(buffer); cornerstone.loadImage(imageId).then(image => cornerstone.displayImage(element, image); document.getElementById('infoPanel').innerHTML = '<span>📌 Sample DICOM (chest CR) loaded. Try dropping your own DICOM file.</span>'; document.getElementById('fileStatus').innerHTML = '📄 Sample: CR-MONO1-10-chest.dcm'; ).catch(e => console.warn("Sample load error (CORS may block raw GitHub? Some browsers restrict) ", e)); ).catch(err => console.log("Sample unavailable. Just drop your own DICOM files."));
// Small resize setTimeout(() => cornerstone.resize(element, true), 100); </script> </body> </html>
3D Slicer is a free, open-source software platform for medical image informatics, image processing, and 3D visualization.
Users can add arrows, text boxes, and "C" marks (for scoliosis). You can also overlay patient demographics (Anonymization feature available for teaching files).
If you are on a Mac, Horos is the gold standard for free DICOM viewing. It is an open-source project that offers functionality often found only in expensive commercial software.
Veterinary PACS software is often an afterthought and overpriced. SmartPACS doesn't care if the patient is human or a Golden Retriever. The free viewer works perfectly for dental X-rays, orthopedic MRIs in horses, and abdominal ultrasounds in cats.
You have contracts to read overnight shifts, but you are working from a laptop. You need a lightweight viewer that doesn't crash. SmartPACS Free loads CT stacks faster than browser-based viewers and works offline if your internet goes down.
While powerful, "free" has fences. To manage expectations, here is what you cannot do with the standard free version: // Drag & Drop handlers dropZone
The Upgrade Path: If you find the free version too limiting, SmartPACS offers a "Pro" or "Workstation" license (usually $50 - $100/month) that unlocks 3D volume rendering, MIP (Maximum Intensity Projection), and DICOM export.
SmartPACS includes preset windowing levels for various body parts. You can quickly switch from "Bone Window" to "Soft Tissue" to "Lung Window" with a single click. Manual adjustment of window width and level is fully supported in the free version.
Our aim is to provide accurate, safe and expert verified information through our articles and social media handles. The remedies, advice and tips mentioned here are for general information only. Please consult your expert before trying any kind of health, beauty, life hacks or astrology related tips. For any feedback or complaint, contact us at .