Implement code changes to enhance functionality and improve performance
This commit is contained in:
+237
-139
@@ -76,7 +76,7 @@ $(document).ready(function () {
|
||||
if (dicom_images.length) {
|
||||
|
||||
for (let element of dicom_images) {
|
||||
setUpDicom(element)
|
||||
setUpDicom3d(element)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -361,159 +361,257 @@ function loadJsonToolStateOnCurrentImage(json) {
|
||||
|
||||
}
|
||||
|
||||
async function setUpDicom(element) {
|
||||
//async function setUpDicom(element) {
|
||||
// console.log("setUpDicom (original)", element);
|
||||
//
|
||||
// $(element).bind('contextmenu', function (e) {
|
||||
// return false;
|
||||
// });
|
||||
//
|
||||
// $(element).dblclick((evt) => {
|
||||
// element.requestFullscreen();
|
||||
// })
|
||||
//
|
||||
// cornerstoneBase64ImageLoader.external.cornerstone = cornerstone;
|
||||
// cornerstoneWebImageLoader.external.cornerstone = cornerstone;
|
||||
// cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
||||
//
|
||||
// cornerstoneTools.init();
|
||||
// const PanTool = cornerstoneTools.PanTool;
|
||||
// const ZoomTool = cornerstoneTools.ZoomTool;
|
||||
// const ZoomMouseWheelTool = cornerstoneTools.ZoomMouseWheelTool;
|
||||
// const WwwcTool = cornerstoneTools.WwwcTool;
|
||||
// const WwwcRegionTool = cornerstoneTools.WwwcRegionTool;
|
||||
// const RotateTool = cornerstoneTools.RotateTool;
|
||||
// const StackScrollTool = cornerstoneTools.StackScrollTool;
|
||||
// const MagnifyTool = cornerstoneTools.MagnifyTool;
|
||||
// const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool;
|
||||
//
|
||||
//
|
||||
// const images = element.dataset.url.split(",");
|
||||
//
|
||||
// //console.log("Dicom - load imageId: ", imageIds);
|
||||
// //for (let index = 0; index < imageIds.length; index++) {
|
||||
// // if (imageIds[index].endsWith("dcm")) {
|
||||
// // imageIds[index] = "wadouri:" + imageIds[index];
|
||||
// // }
|
||||
//
|
||||
// //}
|
||||
// let imageIds = [];
|
||||
// for (let i = 0; i < images.length; i++) {
|
||||
// let data_url = images[i];
|
||||
// // check stack type
|
||||
// if (data_url.startsWith("data:image")) {
|
||||
// let imageId = "base64://" + data_url.split(",")[1];
|
||||
//
|
||||
// imageIds.push(imageId);
|
||||
// } else if (data_url.startsWith("base64://") || data_url.startsWith("wadouri:")) {
|
||||
//
|
||||
// imageIds.push(data_url);
|
||||
//
|
||||
// // Treat application/octet-stream as if they are dicoms
|
||||
// } else if (data_url.startsWith("data:application/dicom") || data_url.startsWith("data:application/octet-stream")) {
|
||||
// //stack = stack.split(";")[1];
|
||||
//
|
||||
// let dfile = await urltoFile(data_url, "dicom", "application/dicom");
|
||||
//
|
||||
// const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(
|
||||
// dfile
|
||||
// );
|
||||
//
|
||||
// loadAnnotation(imageId, annotation);
|
||||
//
|
||||
// imageIds.push(imageId);
|
||||
// //cornerstone.loadImage(imageId).then(function(image) {
|
||||
// // tempFunction(image);
|
||||
// //});
|
||||
// } else {
|
||||
// let url;
|
||||
// // This doesn't seem to have any benefit
|
||||
// //if (data_url.startsWith("http")) {
|
||||
// // url = data_url;
|
||||
// //} else {
|
||||
// // url = window.location.href.replace(/\/\#\/?$/, '') + "/" + data_url
|
||||
// //}
|
||||
// url = data_url;
|
||||
//
|
||||
// if (url.endsWith("dcm")) {
|
||||
// url = "wadouri:" + url;
|
||||
// }
|
||||
//
|
||||
// // if there is no extension treat it as a dicom
|
||||
// if (/(?:\/|^)[^.\/]+$/.test(url)) {
|
||||
// url = "wadouri:" + url;
|
||||
// }
|
||||
//
|
||||
// imageIds.push(url);
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// cornerstone.enable(element);
|
||||
// cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) {
|
||||
// cornerstone.displayImage(element, image);
|
||||
//
|
||||
// cornerstoneTools.addToolForElement(element, PanTool);
|
||||
// cornerstoneTools.addToolForElement(element, ZoomTool);
|
||||
// cornerstoneTools.addToolForElement(element, ZoomMouseWheelTool);
|
||||
// cornerstoneTools.addToolForElement(element, WwwcTool);
|
||||
// cornerstoneTools.addToolForElement(element, WwwcRegionTool);
|
||||
// cornerstoneTools.addToolForElement(element, RotateTool);
|
||||
// cornerstoneTools.addToolForElement(element, StackScrollTool);
|
||||
// cornerstoneTools.addToolForElement(element, MagnifyTool);
|
||||
//
|
||||
// cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, {
|
||||
// configuration: {
|
||||
// getTextCallback: () => {},
|
||||
// changeTextCallback: () => {},
|
||||
// allowEmptyLabel: true,
|
||||
// renderDashed: false,
|
||||
// drawHandles: false,
|
||||
// drawHandlesOnHover: true,
|
||||
// },
|
||||
// });
|
||||
//
|
||||
//
|
||||
//
|
||||
// // Enable our tools
|
||||
// // Avoid incorrect aspect ratio
|
||||
// cornerstoneTools.setToolActiveForElement(element, "Pan", {
|
||||
// mouseButtonMask: 1
|
||||
// });
|
||||
// cornerstoneTools.setToolActiveForElement(element, "Wwwc", {
|
||||
// mouseButtonMask: 2
|
||||
// });
|
||||
// cornerstoneTools.setToolActiveForElement(element, "ZoomMouseWheel", {
|
||||
// mouseButtonMask: 3
|
||||
// });
|
||||
// cornerstoneTools.setToolActiveForElement(element, "Zoom", {
|
||||
// mouseButtonMask: 4
|
||||
// });
|
||||
//
|
||||
// if (element.dataset.edit_annotation == "true") {
|
||||
// cornerstoneTools.setToolActiveForElement(element, "ArrowAnnotate", {
|
||||
// mouseButtonMask: 2
|
||||
// });
|
||||
// } else {
|
||||
// cornerstoneTools.setToolEnabledForElement(element, "ArrowAnnotate");
|
||||
// }
|
||||
//
|
||||
// if (element.dataset.annotations) {
|
||||
// loadJsonToolStateOnCurrentImage(element.dataset.annotations)
|
||||
// }
|
||||
//
|
||||
// cornerstone.resize(element);
|
||||
//
|
||||
//
|
||||
// }).catch((err, err2) => {
|
||||
// console.log(err);
|
||||
// });
|
||||
//
|
||||
//}
|
||||
//console.log("setUpDicom defined");
|
||||
//
|
||||
//// keep reference to the existing 2D setup
|
||||
//window.setUpDicomClassic = setUpDicom;
|
||||
|
||||
console.log("Dicom element found ", $(element));
|
||||
async function setUpDicom3d(element) {
|
||||
console.log("setUpDicom3d (cornerstone3d) for", element);
|
||||
|
||||
$(element).bind('contextmenu', function (e) {
|
||||
return false;
|
||||
});
|
||||
|
||||
$(element).dblclick((evt) => {
|
||||
element.requestFullscreen();
|
||||
})
|
||||
|
||||
cornerstoneBase64ImageLoader.external.cornerstone = cornerstone;
|
||||
cornerstoneWebImageLoader.external.cornerstone = cornerstone;
|
||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
||||
|
||||
cornerstoneTools.init();
|
||||
const PanTool = cornerstoneTools.PanTool;
|
||||
const ZoomTool = cornerstoneTools.ZoomTool;
|
||||
const ZoomMouseWheelTool = cornerstoneTools.ZoomMouseWheelTool;
|
||||
const WwwcTool = cornerstoneTools.WwwcTool;
|
||||
const WwwcRegionTool = cornerstoneTools.WwwcRegionTool;
|
||||
const RotateTool = cornerstoneTools.RotateTool;
|
||||
const StackScrollTool = cornerstoneTools.StackScrollTool;
|
||||
const MagnifyTool = cornerstoneTools.MagnifyTool;
|
||||
const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool;
|
||||
|
||||
|
||||
const images = element.dataset.url.split(",");
|
||||
|
||||
//console.log("Dicom - load imageId: ", imageIds);
|
||||
//for (let index = 0; index < imageIds.length; index++) {
|
||||
// if (imageIds[index].endsWith("dcm")) {
|
||||
// imageIds[index] = "wadouri:" + imageIds[index];
|
||||
// }
|
||||
|
||||
//}
|
||||
let imageIds = [];
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
let data_url = images[i];
|
||||
// check stack type
|
||||
if (data_url.startsWith("data:image")) {
|
||||
let imageId = "base64://" + data_url.split(",")[1];
|
||||
|
||||
imageIds.push(imageId);
|
||||
} else if (data_url.startsWith("base64://") || data_url.startsWith("wadouri:")) {
|
||||
|
||||
imageIds.push(data_url);
|
||||
|
||||
// Treat application/octet-stream as if they are dicoms
|
||||
} else if (data_url.startsWith("data:application/dicom") || data_url.startsWith("data:application/octet-stream")) {
|
||||
//stack = stack.split(";")[1];
|
||||
|
||||
let dfile = await urltoFile(data_url, "dicom", "application/dicom");
|
||||
|
||||
const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(
|
||||
dfile
|
||||
);
|
||||
|
||||
loadAnnotation(imageId, annotation);
|
||||
|
||||
imageIds.push(imageId);
|
||||
//cornerstone.loadImage(imageId).then(function(image) {
|
||||
// tempFunction(image);
|
||||
//});
|
||||
} else {
|
||||
let url;
|
||||
// This doesn't seem to have any benefit
|
||||
//if (data_url.startsWith("http")) {
|
||||
// url = data_url;
|
||||
//} else {
|
||||
// url = window.location.href.replace(/\/\#\/?$/, '') + "/" + data_url
|
||||
//}
|
||||
url = data_url;
|
||||
|
||||
if (url.endsWith("dcm")) {
|
||||
url = "wadouri:" + url;
|
||||
}
|
||||
|
||||
// if there is no extension treat it as a dicom
|
||||
if (/(?:\/|^)[^.\/]+$/.test(url)) {
|
||||
url = "wadouri:" + url;
|
||||
}
|
||||
|
||||
imageIds.push(url);
|
||||
|
||||
|
||||
}
|
||||
// parse images from dataset
|
||||
let raw = element.dataset.url || "";
|
||||
if (!raw) return;
|
||||
let images;
|
||||
try {
|
||||
images = JSON.parse(raw);
|
||||
} catch (e) {
|
||||
images = raw.split(",").map(s => s.trim()).filter(Boolean);
|
||||
}
|
||||
if (!images || images.length === 0) return;
|
||||
|
||||
cornerstone.enable(element);
|
||||
cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) {
|
||||
cornerstone.displayImage(element, image);
|
||||
// ensure element has a viewport-like appearance
|
||||
element.style.width = element.style.width || "500px";
|
||||
element.style.height = element.style.height || "500px";
|
||||
element.style.position = element.style.position || "relative";
|
||||
element.innerHTML = ""; // clear
|
||||
|
||||
cornerstoneTools.addToolForElement(element, PanTool);
|
||||
cornerstoneTools.addToolForElement(element, ZoomTool);
|
||||
cornerstoneTools.addToolForElement(element, ZoomMouseWheelTool);
|
||||
cornerstoneTools.addToolForElement(element, WwwcTool);
|
||||
cornerstoneTools.addToolForElement(element, WwwcRegionTool);
|
||||
cornerstoneTools.addToolForElement(element, RotateTool);
|
||||
cornerstoneTools.addToolForElement(element, StackScrollTool);
|
||||
cornerstoneTools.addToolForElement(element, MagnifyTool);
|
||||
// create a unique rendering engine / viewport ids per element
|
||||
const renderingEngineId = `rendingEngine`;
|
||||
const viewportId = `CT_AXIAL-STACK`;
|
||||
|
||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, {
|
||||
configuration: {
|
||||
getTextCallback: () => {},
|
||||
changeTextCallback: () => {},
|
||||
allowEmptyLabel: true,
|
||||
renderDashed: false,
|
||||
drawHandles: false,
|
||||
drawHandlesOnHover: true,
|
||||
},
|
||||
try {
|
||||
// dynamic import of cornerstone3D core + dicom loader
|
||||
const coreModule = window.cornerstone3d
|
||||
const dicomLoaderModule = window.cornerstoneDICOMImageLoader
|
||||
|
||||
await coreModule.init();
|
||||
await dicomLoaderModule.init();
|
||||
|
||||
const { RenderingEngine, Enums } = coreModule;
|
||||
const { chunkManager } = dicomLoaderModule; // may exist for some setups
|
||||
|
||||
// create engine and enable a Stack viewport
|
||||
const renderingEngine = new RenderingEngine(renderingEngineId);
|
||||
console.log(renderingEngine)
|
||||
|
||||
const viewportInput = {
|
||||
viewportId,
|
||||
type: Enums.ViewportType.STACK,
|
||||
element,
|
||||
//viewportType: Enums.ViewportType.STACK, // Stack viewport for slice stacks
|
||||
};
|
||||
|
||||
renderingEngine.enableElement(viewportInput);
|
||||
|
||||
const viewport = renderingEngine.getViewport(viewportId);
|
||||
|
||||
// Prepare imageIds: ensure remote URLs are usable by dicom-image-loader (wadouri:)
|
||||
const imageIds = images.map((url) => {
|
||||
url = url.trim();
|
||||
// if it's already a scheme we pass through; otherwise treat as wadouri
|
||||
if (/^(wadouri:|base64:|data:)/i.test(url)) return url;
|
||||
return `wadouri:${url}`;
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Enable our tools
|
||||
// Avoid incorrect aspect ratio
|
||||
cornerstoneTools.setToolActiveForElement(element, "Pan", {
|
||||
mouseButtonMask: 1
|
||||
});
|
||||
cornerstoneTools.setToolActiveForElement(element, "Wwwc", {
|
||||
mouseButtonMask: 2
|
||||
});
|
||||
cornerstoneTools.setToolActiveForElement(element, "ZoomMouseWheel", {
|
||||
mouseButtonMask: 3
|
||||
});
|
||||
cornerstoneTools.setToolActiveForElement(element, "Zoom", {
|
||||
mouseButtonMask: 4
|
||||
});
|
||||
|
||||
if (element.dataset.edit_annotation == "true") {
|
||||
cornerstoneTools.setToolActiveForElement(element, "ArrowAnnotate", {
|
||||
mouseButtonMask: 2
|
||||
});
|
||||
} else {
|
||||
cornerstoneTools.setToolEnabledForElement(element, "ArrowAnnotate");
|
||||
// If dicom-image-loader provides a metadata cache factory, pre-cache metadata
|
||||
if (typeof dicomLoaderModule.createImageIdsAndCacheMetaData === "function") {
|
||||
try {
|
||||
// attempt to call helper to cache meta-data for the first image (best-effort)
|
||||
await dicomLoaderModule.createImageIdsAndCacheMetaData({
|
||||
imageIds,
|
||||
});
|
||||
} catch (e) {
|
||||
// not fatal — continue
|
||||
console.warn("createImageIdsAndCacheMetaData failed (continuing):", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (element.dataset.annotations) {
|
||||
loadJsonToolStateOnCurrentImage(element.dataset.annotations)
|
||||
}
|
||||
await viewport.setStack(imageIds, 0);
|
||||
|
||||
cornerstone.resize(element);
|
||||
viewport.render();
|
||||
|
||||
// store references for debugging/use elsewhere
|
||||
element._cornerstone3d = {
|
||||
renderingEngineId,
|
||||
viewportId,
|
||||
renderingEngine,
|
||||
viewport,
|
||||
imageIds,
|
||||
};
|
||||
|
||||
}).catch((err, err2) => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
console.log("setUpDicom3d complete", element._cornerstone3d);
|
||||
return element._cornerstone3d;
|
||||
} catch (err) {
|
||||
console.error("setUpDicom3d failed:", err);
|
||||
// per request: no fallback here — rethrow so caller can handle if desired
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
window.setUpDicom = setUpDicom;
|
||||
// expose globally like existing code expects
|
||||
window.setUpDicom = setUpDicom3d;
|
||||
|
||||
|
||||
//function keyUpHandler(e) {
|
||||
// if (e.key == "Control") {
|
||||
|
||||
+615
-188
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user