Skip to content

Instantly share code, notes, and snippets.

@prerakmody
Created January 24, 2024 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prerakmody/e52ac524f73350ea6463b3e7a18600a1 to your computer and use it in GitHub Desktop.
Save prerakmody/e52ac524f73350ea6463b3e7a18600a1 to your computer and use it in GitHub Desktop.
Cornerstone.js for loading a folder of .dcm files
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://unpkg.com/cornerstone-core/dist/cornerstone.js"></script> <!-- cornerstone-core - 2.6.1 - 2021-11-19 -->
<script src="https://unpkg.com/cornerstone-tools/dist/cornerstoneTools.js"></script> <!-- cornerstone-tools - 6.0.10 - 2023-07-21 -->
<script src="https://unpkg.com/cornerstone-math/dist/cornerstoneMath.js"></script> <!-- cornerstone-math - 0.1.10 - 2022-06-09 -->
<script src="https://unpkg.com/dicom-parser/dist/dicomParser.js"></script>
<script src="https://unpkg.com/cornerstone-wado-image-loader/dist//cornerstoneWADOImageLoader.bundle.min.js"></script>
<!-- create a css block-->
<style>
.pressed {
background-color: #259736;
}
</style>
</head>
<body>
<input type="file" id="dicomFolder" webkitdirectory multiple />
<div id="content" style="display: flex; align-items: stretch; justify-content: stretch;">
<!-- <button id="freehandRoiButton" style="display: none;">Draw</button> -->
</div>
<script>
// Step 0.1 - Enable debugging to see verbose logs
localStorage.setItem("debug", "cornerstoneTools")
// Step 0.2 - Connect libraries
cornerstoneTools.external.Hammer = Hammer;
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
cornerstoneWADOImageLoader.external.cornerstoneTools = cornerstoneTools;
// Step 0.3 - Initialize libraries
cornerstoneTools.init()
// Step 0.4 - Enable main div
var element = document.getElementById('content');
cornerstone.enable(element);
// Step 0.5 - gobal vars
var isFreehandRoiActive = false;
var isContourSculptorActive = false;
// Step 1 - Get .dcm folder
document.getElementById('dicomFolder').addEventListener('change', async function(e) {
// Step 1.1 - get WADO image Ids
var files = e.target.files;
var imageIds = Array.from(files).map(file => {
return cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
});
// Step 1.2 - Load and sort images based on InstanceNumber
var images = await Promise.all(imageIds.map(id => cornerstone.loadImage(id)));
var firstImage = images[0];
element.style.width = firstImage.columns + 'px';
element.style.height = firstImage.rows + 'px';
images.sort((a, b) => parseInt(dicomParser.parseDicom(a.data.byteArray).string('x00200013')) - dicomParser.parseDicom(b.data.byteArray).string('x00200013'));
imageIds = images.map(image => image.imageId);
// Step 1.3 - Load all images in the stack
var stack = {
currentImageIdIndex: 0,
imageIds: imageIds
};
// Step 1.4 - Load images and set the stack
cornerstone.loadImage(imageIds[parseInt(imageIds.length/2)]).then((image) => {
// Step 1.4.1 - Show first image
cornerstone.displayImage(element, image)
// Step 1.4.2 - Set width and height
var canvas = document.querySelector('#content canvas');
canvas.width = image.columns
canvas.height = image.rows
canvas.addEventListener('contextmenu', function(event) {
event.preventDefault();
});
// Step 1.4.3 - Add stack state manager and tool state
cornerstoneTools.addStackStateManager(element, ['stack'])
cornerstoneTools.addToolState(element, 'stack', stack)
// Step 1.4.4 - Make buttons
var freehandRoiButton = document.createElement("button")
freehandRoiButton.id = "freehandRoiButton"
freehandRoiButton.innerHTML = "Draw"
element.appendChild(freehandRoiButton)
var contourSculptorButton = document.createElement("button");
contourSculptorButton.id = "contourSculptorButton";
contourSculptorButton.innerHTML = "Contour Sculpting";
element.appendChild(contourSculptorButton);
// Step 1.4.4.1 - Events for FreehandRoi
freehandRoiButton.addEventListener('click', function() {
isFreehandRoiActive = !isFreehandRoiActive;
if (isFreehandRoiActive) {
cornerstoneTools.setToolActive('FreehandRoi', { mouseButtonMask: 1 });
freehandRoiButton.classList.add('pressed');
cornerstoneTools.setToolPassive('FreehandRoiSculptor', {});
contourSculptorButton.classList.remove('pressed');
isContourSculptorActive = false;
} else {
cornerstoneTools.setToolPassive('FreehandRoi', {});
freehandRoiButton.classList.remove('pressed');
}
});
// Step 1.4.4.2 - Events for contourSculptorButton
contourSculptorButton.addEventListener('click', function() {
isContourSculptorActive = !isContourSculptorActive;
if (isContourSculptorActive) {
cornerstoneTools.setToolActive('FreehandRoiSculptor', { mouseButtonMask: 1 });
contourSculptorButton.classList.add('pressed');
cornerstoneTools.setToolPassive('FreehandRoi', {});
freehandRoiButton.classList.remove('pressed');
isFreehandRoiActive = false;
} else {
cornerstoneTools.setToolPassive('FreehandRoiSculptor', {});
contourSculptorButton.classList.remove('pressed');
}
});
})
});
// Step 2 - Add tools
// Step 2.1 - Add mouse wheel tool
const StackScrollMouseWheelTool = cornerstoneTools.StackScrollMouseWheelTool
cornerstoneTools.addTool(StackScrollMouseWheelTool)
// cornerstoneTools.setToolActive('StackScrollMouseWheel', { })
// Step 2.1 - Add freehand tool (left mouse button)
// https://tools.cornerstonejs.org/examples/tools/freehand-mouse.html
const FreehandRoiTool = cornerstoneTools.FreehandRoiTool
cornerstoneTools.addTool(FreehandRoiTool)
document.addEventListener('keydown', function(event) {
const freehandRoiToolState = cornerstoneTools.getToolState(element, 'FreehandRoi');
if (event.key === 'Escape') {
if (freehandRoiToolState && freehandRoiToolState.data && freehandRoiToolState.data.length > 0) {
if (freehandRoiToolState.data[freehandRoiToolState.data.length - 1].active == true){
cornerstoneTools.setToolPassive('FreehandRoi', {});
freehandRoiToolState.data.pop();
cornerstone.updateImage(element);
cornerstoneTools.setToolActive('FreehandRoi', { mouseButtonMask: 1 })
}
}
}
});
// Step 2.2 - Add the contour sculptor tool
const FreehandRoiSculptorTool = cornerstoneTools.FreehandRoiSculptorTool;
cornerstoneTools.addTool(FreehandRoiSculptorTool);
cornerstoneTools.setToolActive('FreehandRoiSculptor', {});
// var config = cornerstoneTools.getToolState('FreehandRoiSculptor');
// console.log(config);
// Step 2.3 - Add zoom tool (right mouse button)
const ZoomTool = cornerstoneTools.ZoomTool
cornerstoneTools.addTool(ZoomTool)
cornerstoneTools.setToolActive('Zoom', { mouseButtonMask: 2 })
// Step 2.4 - Add pan tool (middle mouse button)
const PanTool = cornerstoneTools.PanTool;
cornerstoneTools.addTool(PanTool);
cornerstoneTools.setToolActive('Pan', { mouseButtonMask: 4 });
</script>
</body>
</html>
<!--
npm install @cornerstonejs/core @cornerstonejs/streaming-image-volume-loader @cornerstonejs/tools @cornerstonejs/dicom-image-loader
npm install --save cornerstone-tools
-->
<!--
New tools to check
- https://github.com/cornerstonejs/cornerstoneTools/issues/1061
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment