diff --git a/dicom-viewer/package.json b/dicom-viewer/package.json index b83d8dc..4b68591 100644 --- a/dicom-viewer/package.json +++ b/dicom-viewer/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc && vite build && cp dist/index.js /home/ross/rad/rad/rad/static/dv3d/index.js", + "build": "tsc && vite build && cp dist/index.js /home/ross/penracourses/rad/rad/static/dv3d/index.js", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, diff --git a/dicom-viewer/src/App.tsx b/dicom-viewer/src/App.tsx index d4a5893..d9e4c36 100644 --- a/dicom-viewer/src/App.tsx +++ b/dicom-viewer/src/App.tsx @@ -442,8 +442,18 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer const onError = (ev: ErrorEvent) => { try { const msg = ev && ev.message ? String(ev.message) : ''; - if (msg.includes('releaseGraphicsResources') || msg.includes('openGLTexture')) { - console.error('Detected graphics resource error:', ev); + // Detect known rendering/WebGL-related errors and actor/colormap issues + if ( + msg.includes('releaseGraphicsResources') || + msg.includes('openGLTexture') || + msg.includes('getDefaultActor') || + msg.includes('setColormapGPU') || + msg.includes("can't access property \"actor\"") || + // generic rendering failure + msg.toLowerCase().includes('webgl') || + msg.toLowerCase().includes('colormap') + ) { + console.error('Detected graphics/rendering error:', ev); setGraphicsErrorMessage(msg || null); setGraphicsErrorVisible(true); } @@ -456,8 +466,16 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer try { const reason = (ev && (ev as any).reason) || ''; const text = typeof reason === 'string' ? reason : (reason && reason.message) ? reason.message : String(reason); - if (text.includes('releaseGraphicsResources') || text.includes('openGLTexture')) { - console.error('Detected graphics resource rejection:', ev); + if ( + text.includes('releaseGraphicsResources') || + text.includes('openGLTexture') || + text.includes('getDefaultActor') || + text.includes('setColormapGPU') || + text.includes("can't access property \"actor\"") || + text.toLowerCase().includes('webgl') || + text.toLowerCase().includes('colormap') + ) { + console.error('Detected graphics/rendering rejection:', ev); setGraphicsErrorMessage(text || null); setGraphicsErrorVisible(true); } @@ -1402,47 +1420,51 @@ function App({ container_id, imageStacks, autoCacheStack, annotationJson, viewer dicomImageLoaderInit(); // Register client-side image loader for external images (JPEG/PNG/blob/data) try { - imageLoader.registerImageLoader('external', async (imageId: string) => { - // imageId expected as 'external:' - const url = imageId.replace(/^external:/, ''); - const img = new Image(); - img.crossOrigin = 'anonymous'; - img.src = url; - await new Promise((resolve, reject) => { - img.onload = () => resolve(true); - img.onerror = (e) => reject(e); - }); + imageLoader.registerImageLoader('external', (imageId: string) => { + const promise = (async () => { + // imageId expected as 'external:' + const url = imageId.replace(/^external:/, ''); + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.src = url; + await new Promise((resolve, reject) => { + img.onload = () => resolve(true); + img.onerror = (e) => reject(e); + }); - const w = img.naturalWidth || img.width; - const h = img.naturalHeight || img.height; - const canvas = document.createElement('canvas'); - canvas.width = w; - canvas.height = h; - const ctx = canvas.getContext('2d'); - if (!ctx) throw new Error('Unable to create canvas context'); - ctx.drawImage(img, 0, 0, w, h); - const im = ctx.getImageData(0, 0, w, h); + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + const canvas = document.createElement('canvas'); + canvas.width = w; + canvas.height = h; + const ctx = canvas.getContext('2d'); + if (!ctx) throw new Error('Unable to create canvas context'); + ctx.drawImage(img, 0, 0, w, h); + const im = ctx.getImageData(0, 0, w, h); - const image = { - imageId, - minPixelValue: 0, - maxPixelValue: 255, - slope: 1.0, - intercept: 0, - rows: h, - columns: w, - height: h, - width: w, - color: true, - rgba: true, - sizeInBytes: im.data.length, - getPixelData: () => im.data, - // Some Cornerstone APIs expect `getImageData` or `getCanvas` - provide canvas and ImageData - getImageData: () => im, - getCanvas: () => canvas, - } as any; + const image = { + imageId, + minPixelValue: 0, + maxPixelValue: 255, + slope: 1.0, + intercept: 0, + rows: h, + columns: w, + height: h, + width: w, + color: true, + rgba: true, + sizeInBytes: im.data.length, + getPixelData: () => im.data, + // Some Cornerstone APIs expect `getImageData` or `getCanvas` - provide canvas and ImageData + getImageData: () => im, + getCanvas: () => canvas, + } as any; - return image; + return image; + })(); + + return { promise }; }); } catch (e) { console.warn('Failed to register external image loader', e);