UNPKG

@cleerlycode/cornerstone-wado-image-loader

Version:
312 lines (269 loc) 14.5 kB
<!DOCTYPE HTML> <html> <head> <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone --> <link href="../bootstrap.min.css" rel="stylesheet"> <link href="../cornerstone.min.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="page-header"> <h1>Example of displaying a DICOM P10 from the local file system</h1> <p class="lead"> Click "Choose File" and select a DICOM P10 file on your local file system or drag and drop a DICOM P10 file. <button id="toggleCollapseInfo" class="btn btn-primary" type="button"> Click for more info </button> </p> </div> <div id="collapseInfo" class="collapse" style="display:none;"> <p> This example illustrates how to use the cornerstoneWADOImageLoader to read a DICOM P10 SOP instance from the local file system and display it in your web browser using cornerstone. Not all transfer syntaxes are currently supported, <a href="https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/docs/TransferSyntaxes.md"> click here for the full list. </a> </p> <P> NOTE: If the DICOM P10 file is multiframe, only the first frame will be displayed. Access to other frames is possible by adding the query string parameter <i>frame</i> to specify which frame to display from a multiframe object (defaults to the first frame if not specified). <code>?frame=2</code> </P> <P> NOTE: Browser security prevents javascript from reading the file system directly - files must be chosen manually by the user via the file input element as shown in this example or via drag and drop. </P> <br> <br> <strong>Use of this example requires IE10+ or any other modern browser.</strong> <hr> </div> <div id="loadProgress">Image Load Progress:</div> <div class="row"> <form id="form" class="form-horizontal"> <div class="form-group"> <div class="col-sm-3"> <input type="file" id="selectFile" > </div> </div> </form> </div> <input type="checkbox" id="toggleModalityLUT">Apply Modality LUT</input> <input type="checkbox" id="toggleVOILUT">Apply VOI LUT</input> <br> <div class="row"> <div class="col-md-6"> <div style="width:512px;height:512px;position:relative;color: white;display:inline-block;border-style:solid;border-color:black;" oncontextmenu="return false" class='disable-selection noIbar' unselectable='on' onselectstart='return false;' onmousedown='return false;'> <div id="dicomImage" style="width:512px;height:512px;top:0px;left:0px; position:absolute"> </div> </div> </div> <div class="col-md-6"> <span>Transfer Syntax: </span><span id="transferSyntax"></span><br> <span>SOP Class: </span><span id="sopClass"></span><br> <span>Samples Per Pixel: </span><span id="samplesPerPixel"></span><br> <span>Photometric Interpretation: </span><span id="photometricInterpretation"></span><br> <span>Number Of Frames: </span><span id="numberOfFrames"></span><br> <span>Planar Configuration: </span><span id="planarConfiguration"></span><br> <span>Rows: </span><span id="rows"></span><br> <span>Columns: </span><span id="columns"></span><br> <span>Pixel Spacing: </span><span id="pixelSpacing"></span><br> <span>Bits Allocated: </span><span id="bitsAllocated"></span><br> <span>Bits Stored: </span><span id="bitsStored"></span><br> <span>High Bit: </span><span id="highBit"></span><br> <span>Pixel Representation: </span><span id="pixelRepresentation"></span><br> <span>WindowCenter: </span><span id="windowCenter"></span><br> <span>WindowWidth: </span><span id="windowWidth"></span><br> <span>RescaleIntercept: </span><span id="rescaleIntercept"></span><br> <span>RescaleSlope: </span><span id="rescaleSlope"></span><br> <span>Basic Offset Table Entries: </span><span id="basicOffsetTable"></span><br> <span>Fragments: </span><span id="fragments"></span><br> <span>Min Stored Pixel Value: </span><span id="minStoredPixelValue"></span><br> <span>Max Stored Pixel Value: </span><span id="maxStoredPixelValue"></span><br> <span>Total Time: </span><span id="totalTime"></span><br> <span>Load Time: </span><span id="loadTime"></span><br> <span>Decode Time: </span><span id="decodeTime"></span><br> </div> </div> </div> </body> <!-- include the cornerstone library --> <script src="../cornerstone.min.js"></script> <SCRIPT src="../cornerstoneMath.min.js"></SCRIPT> <SCRIPT src="../cornerstoneTools.min.js"></SCRIPT> <!-- include the dicomParser library as the WADO image loader depends on it --> <script src="../dicomParser.min.js"></script> <!-- BEGIN Optional Codecs --> <!-- OpenJPEG based jpeg 2000 codec --> <script src="../../codecs/openJPEG-FixedMemory.js"></script> <!-- PDF.js based jpeg 2000 codec --> <!-- NOTE: do not load the OpenJPEG codec if you use this one --> <!--<script src="../../codecs/jpx.min.js"></script>--> <!-- JPEG-LS codec --> <script src="../../codecs/charLS-FixedMemory-browser.js"></script> <!-- JPEG Lossless codec --> <script src="../../codecs/jpegLossless.js"></script> <!-- JPEG Baseline codec --> <script src="../../codecs/jpeg.js"></script> <!-- Deflate transfer syntax codec --> <script src="../../codecs/pako.min.js"></script> <!-- END Optional Codecs --> <!-- include the cornerstoneWADOImageLoader library --> <script src="../../dist/cornerstoneWADOImageLoader.js"></script> <!-- uids --> <script src="uids.js"></script> <script> cornerstoneWADOImageLoader.external.cornerstone = cornerstone; // this function gets called once the user drops the file onto the div function handleFileSelect(evt) { evt.stopPropagation(); evt.preventDefault(); // Get the FileList object that contains the list of files that were dropped const files = evt.dataTransfer.files; // this UI is only built for a single file so just dump the first one file = files[0]; const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file); loadAndViewImage(imageId); } function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Setup the dnd listeners. const dropZone = document.getElementById('dicomImage'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleFileSelect, false); cornerstoneWADOImageLoader.configure({ beforeSend: function(xhr) { // Add custom headers here (e.g. auth tokens) //xhr.setRequestHeader('x-auth-token', 'my auth token'); }, }); let loaded = false; function loadAndViewImage(imageId) { const element = document.getElementById('dicomImage'); const start = new Date().getTime(); cornerstone.loadImage(imageId).then(function(image) { console.log(image); const viewport = cornerstone.getDefaultViewportForImage(element, image); document.getElementById('toggleModalityLUT').checked = (viewport.modalityLUT !== undefined); document.getElementById('toggleVOILUT').checked = (viewport.voiLUT !== undefined); cornerstone.displayImage(element, image, viewport); if(loaded === false) { cornerstoneTools.mouseInput.enable(element); cornerstoneTools.mouseWheelInput.enable(element); cornerstoneTools.wwwc.activate(element, 1); // ww/wc is the default tool for left mouse button cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button cornerstoneTools.zoomWheel.activate(element); // zoom is the default tool for middle mouse wheel cornerstoneTools.imageStats.enable(element); loaded = true; } function getTransferSyntax() { const value = image.data.string('x00020010'); return value + ' [' + uids[value] + ']'; } function getSopClass() { const value = image.data.string('x00080016'); return value + ' [' + uids[value] + ']'; } function getPixelRepresentation() { const value = image.data.uint16('x00280103'); if(value === undefined) { return; } return value + (value === 0 ? ' (unsigned)' : ' (signed)'); } function getPlanarConfiguration() { const value = image.data.uint16('x00280006'); if(value === undefined) { return; } return value + (value === 0 ? ' (pixel)' : ' (plane)'); } document.getElementById('transferSyntax').textContent = getTransferSyntax(); document.getElementById('sopClass').textContent = getSopClass(); document.getElementById('samplesPerPixel').textContent = image.data.uint16('x00280002'); document.getElementById('photometricInterpretation').textContent = image.data.string('x00280004'); document.getElementById('numberOfFrames').textContent = image.data.string('x00280008'); document.getElementById('planarConfiguration').textContent = getPlanarConfiguration(); document.getElementById('rows').textContent = image.data.uint16('x00280010'); document.getElementById('columns').textContent = image.data.uint16('x00280011'); document.getElementById('pixelSpacing').textContent = image.data.string('x00280030'); document.getElementById('bitsAllocated').textContent = image.data.uint16('x00280100'); document.getElementById('bitsStored').textContent = image.data.uint16('x00280101'); document.getElementById('highBit').textContent = image.data.uint16('x00280102'); document.getElementById('pixelRepresentation').textContent = getPixelRepresentation(); document.getElementById('windowCenter').textContent = image.data.string('x00281050'); document.getElementById('windowWidth').textContent = image.data.string('x00281051'); document.getElementById('rescaleIntercept').textContent = image.data.string('x00281052'); document.getElementById('rescaleSlope').textContent = image.data.string('x00281053'); document.getElementById('basicOffsetTable').textContent = image.data.elements.x7fe00010 && image.data.elements.x7fe00010.basicOffsetTable ? image.data.elements.x7fe00010.basicOffsetTable.length : ''; document.getElementById('fragments').textContent = image.data.elements.x7fe00010 && image.data.elements.x7fe00010.fragments ? image.data.elements.x7fe00010.fragments.length : ''; document.getElementById('minStoredPixelValue').textContent = image.minPixelValue; document.getElementById('maxStoredPixelValue').textContent = image.maxPixelValue; const end = new Date().getTime(); const time = end - start; document.getElementById('totalTime').textContent = time + "ms"; document.getElementById('loadTime').textContent = image.loadTimeInMS + "ms"; document.getElementById('decodeTime').textContent = image.decodeTimeInMS + "ms"; }, function(err) { alert(err); }); } cornerstone.events.addEventListener('cornerstoneimageloadprogress', function(event) { const eventData = event.detail; const loadProgress = document.getElementById('loadProgress'); loadProgress.textContent = `Image Load Progress: ${eventData.percentComplete}%`; }); const element = document.getElementById('dicomImage'); cornerstone.enable(element); document.getElementById('selectFile').addEventListener('change', function(e) { // Add the file to the cornerstoneFileImageLoader and get unique // number for that file const file = e.target.files[0]; const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file); loadAndViewImage(imageId); }); document.getElementById('toggleModalityLUT').addEventListener('click', function() { const applyModalityLUT = document.getElementById('toggleModalityLUT').checked; console.log('applyModalityLUT=', applyModalityLUT); const image = cornerstone.getImage(element); const viewport = cornerstone.getViewport(element); if(applyModalityLUT) { viewport.modalityLUT = image.modalityLUT; } else { viewport.modalityLUT = undefined; } cornerstone.setViewport(element, viewport); }); document.getElementById('toggleVOILUT').addEventListener('click', function() { const applyVOILUT = document.getElementById('toggleVOILUT').checked; console.log('applyVOILUT=', applyVOILUT); const image = cornerstone.getImage(element); const viewport = cornerstone.getViewport(element); if(applyVOILUT) { viewport.voiLUT = image.voiLUT; } else { viewport.voiLUT = undefined; } cornerstone.setViewport(element, viewport); }); document.getElementById('toggleCollapseInfo').addEventListener('click', function() { if (document.getElementById('collapseInfo').style.display === 'none') { document.getElementById('collapseInfo').style.display = 'block'; } else { document.getElementById('collapseInfo').style.display = 'none'; } }); </script> </html>