Implement code changes to enhance functionality and improve performance

This commit is contained in:
Ross
2025-09-08 12:09:16 +01:00
parent 6b1db6b3c5
commit 0db1e4c689
2 changed files with 852 additions and 327 deletions
+237 -139
View File
@@ -76,7 +76,7 @@ $(document).ready(function () {
if (dicom_images.length) { if (dicom_images.length) {
for (let element of dicom_images) { 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) { // parse images from dataset
return false; let raw = element.dataset.url || "";
}); if (!raw) return;
let images;
$(element).dblclick((evt) => { try {
element.requestFullscreen(); images = JSON.parse(raw);
}) } catch (e) {
images = raw.split(",").map(s => s.trim()).filter(Boolean);
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);
}
} }
if (!images || images.length === 0) return;
cornerstone.enable(element); // ensure element has a viewport-like appearance
cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) { element.style.width = element.style.width || "500px";
cornerstone.displayImage(element, image); element.style.height = element.style.height || "500px";
element.style.position = element.style.position || "relative";
element.innerHTML = ""; // clear
cornerstoneTools.addToolForElement(element, PanTool); // create a unique rendering engine / viewport ids per element
cornerstoneTools.addToolForElement(element, ZoomTool); const renderingEngineId = `rendingEngine`;
cornerstoneTools.addToolForElement(element, ZoomMouseWheelTool); const viewportId = `CT_AXIAL-STACK`;
cornerstoneTools.addToolForElement(element, WwwcTool);
cornerstoneTools.addToolForElement(element, WwwcRegionTool);
cornerstoneTools.addToolForElement(element, RotateTool);
cornerstoneTools.addToolForElement(element, StackScrollTool);
cornerstoneTools.addToolForElement(element, MagnifyTool);
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { try {
configuration: { // dynamic import of cornerstone3D core + dicom loader
getTextCallback: () => {}, const coreModule = window.cornerstone3d
changeTextCallback: () => {}, const dicomLoaderModule = window.cornerstoneDICOMImageLoader
allowEmptyLabel: true,
renderDashed: false, await coreModule.init();
drawHandles: false, await dicomLoaderModule.init();
drawHandlesOnHover: true,
}, 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}`;
}); });
// If dicom-image-loader provides a metadata cache factory, pre-cache metadata
if (typeof dicomLoaderModule.createImageIdsAndCacheMetaData === "function") {
// Enable our tools try {
// Avoid incorrect aspect ratio // attempt to call helper to cache meta-data for the first image (best-effort)
cornerstoneTools.setToolActiveForElement(element, "Pan", { await dicomLoaderModule.createImageIdsAndCacheMetaData({
mouseButtonMask: 1 imageIds,
}); });
cornerstoneTools.setToolActiveForElement(element, "Wwwc", { } catch (e) {
mouseButtonMask: 2 // not fatal — continue
}); console.warn("createImageIdsAndCacheMetaData failed (continuing):", e);
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) { await viewport.setStack(imageIds, 0);
loadJsonToolStateOnCurrentImage(element.dataset.annotations)
}
cornerstone.resize(element); viewport.render();
// store references for debugging/use elsewhere
element._cornerstone3d = {
renderingEngineId,
viewportId,
renderingEngine,
viewport,
imageIds,
};
}).catch((err, err2) => { console.log("setUpDicom3d complete", element._cornerstone3d);
console.log(err); 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) { //function keyUpHandler(e) {
// if (e.key == "Control") { // if (e.key == "Control") {
+615 -188
View File
File diff suppressed because one or more lines are too long