# 图像加载失败问题分析 ## 问题现象 - WebGL 警告出现但不崩溃 - 图像没有显示出来 - 错误发生在切换胶片时的自动加载 (`loadImageFromProps`) ## 根本原因 ### 时序竞争问题 ```typescript // 当组件重新创建时(由于 React key 修复) 1. useEffect() 开始执行 - 初始化渲染引擎和 viewport 2. useEffect([imageId, stackViewport]) 同时触发 - 尝试加载图像 3. 但是 WebGL 上下文可能还没有完全稳定 4. 导致图像加载在不稳定的上下文中失败 ``` ### WebGL 上下文初始化不完整 - 新创建的 WebGL 上下文需要时间来检查和加载扩展 - `OES_texture_float_linear` 检查失败可能影响后续的纹理操作 - 虽然 Cornerstone 会尝试降级,但可能导致初次加载失败 ## 解决方案 ### 方案1:延迟图像加载 ```typescript useEffect(() => { const loadImageFromProps = async () => { if (!stackViewport) return; // 给 WebGL 上下文一些时间稳定 await new Promise(resolve => setTimeout(resolve, 100)); // 避免重复加载相同图像 if (imageId === currentImageId) return; if (imageId && imageId.trim() !== '') { console.log(`[DcmCell] 开始从 props 加载图像: ${imageId}`); const success = await loadImage(imageId, 'props'); if (success) { setCurrentImageId(imageId); } } else { // 清空逻辑... } }; loadImageFromProps(); }, [imageId, stackViewport]); ``` ### 方案2:检查 WebGL 状态 ```typescript const isWebGLContextStable = () => { const canvas = viewportRef.current?.querySelector('canvas'); if (!canvas) return false; const gl = canvas.getContext('webgl') || canvas.getContext('webgl2'); return gl && gl.getError() === gl.NO_ERROR; }; ``` ### 方案3:改进错误处理和重试 ```typescript const loadImage = async (targetImageId: string, source: 'props' | 'drag' = 'props', retryCount = 0): Promise => { if (!stackViewport || !targetImageId) return false; try { const fullImageUrl = targetImageId.startsWith('dicomweb:') ? targetImageId : getDcmImageUrl(targetImageId); await stackViewport.setStack([fullImageUrl], 0); stackViewport.render(); setHasImage(true); console.log(`[DcmCell] 图像加载成功 (${source}): ${targetImageId}`); return true; } catch (error) { console.error(`[DcmCell] 图像加载失败 (${source}):`, error); // 如果是 WebGL 相关错误且还没重试过,进行重试 if (retryCount === 0 && error.message && (error.message.includes('WebGL') || error.message.includes('texture'))) { console.log(`[DcmCell] WebGL 错误,1秒后重试...`); await new Promise(resolve => setTimeout(resolve, 1000)); return loadImage(targetImageId, source, 1); } setHasImage(false); return false; } }; ``` ## 推荐解决步骤 1. 首先尝试延迟加载方案(最简单) 2. 如果仍有问题,添加错误重试机制 3. 最后考虑 WebGL 状态检查