Enhance DICOM 3D loader to fallback to 2D loader for standard web images and handle 'https' URLs

This commit is contained in:
Ross
2025-11-10 11:15:52 +00:00
parent 0be605b41d
commit 4d97e9e881
+45 -6
View File
@@ -602,16 +602,41 @@ async function setUpDicom3d(element) {
// but avoid forcing wadouri: for standard web images (png/jpg/etc) because
// the dicom parser will fail when given non-DICOM files. For such images
// return the raw URL so the appropriate web-image loader can handle them.
// If any image looks like a plain web image (png/jpg/etc) prefer the
// existing 2D cornerstone loader which handles http(s) image schemes.
// This avoids a situation where the 3D dicom loader has no handler for
// the 'https' scheme and throws "No image loader found for scheme 'https'".
const looksLikeWebImage = (u) => {
if (!u) return false;
try { u = u.trim(); } catch (e) {}
if (u.startsWith('data:image')) return true;
if (u.match(/\.(png|jpe?g|gif|bmp|webp)$/i)) return true;
return false;
};
if (images.some(looksLikeWebImage)) {
// Fallback: use the 2D cornerstone loader which has web-image handling
// and is more tolerant of raw http(s) URLs. We reuse the project's
// dicomViewer helper (it expects a jQuery element).
console.warn('setUpDicom3d: contains web-image(s) — falling back to 2D loader');
try {
// annotations are not available in this scope in the 3d code path; pass
// undefined for annotations and let the loader handle it.
dicomViewer.loadCornerstone($(element), null, images, undefined, images.length > 5);
// store a lightweight marker so callers can inspect what happened
element._cornerstone3d = { fallback: 'cornerstone2d', imageCount: images.length };
return element._cornerstone3d;
} catch (err) {
console.warn('Fallback 2D loader failed; will continue to try 3D loader', err);
// fallthrough to attempt 3D loading below
}
}
const imageIds = images.map((url) => {
url = url.trim();
// if it's already a scheme we pass through
if (/^(wadouri:|base64:|data:|http:|https:)/i.test(url)) return url;
// If the URL looks like a regular web image, don't treat it as DICOM
if (url.match(/\.(png|jpe?g|gif|bmp|webp)$/i)) {
return url;
}
// default: treat as wadouri (likely a DICOM file)
return `wadouri:${url}`;
});
@@ -629,7 +654,21 @@ async function setUpDicom3d(element) {
}
}
await viewport.setStack(imageIds, 0);
try {
await viewport.setStack(imageIds, 0);
} catch (err) {
// If the 3D loader fails because it doesn't know how to load 'https'
// URLs, fallback to the 2D cornerstone loader which handles web images.
console.warn('viewport.setStack failed, attempting 2D fallback:', err);
try {
dicomViewer.loadCornerstone($(element), null, images, undefined, images.length > 5);
element._cornerstone3d = { fallback: 'cornerstone2d', imageCount: images.length };
return element._cornerstone3d;
} catch (err2) {
console.error('2D fallback also failed:', err2);
throw err; // rethrow original error
}
}
viewport.render();