{{ v.currentFileName }}
+ {{ `${ v.currentImageIdIndex + 1 } / ${ v.imageIds.length }` }}
+
+
{{ `Zoom: ${v.zoomText}` }}
{ return }"
@@ -107,6 +111,12 @@
@click="setToolActive('PlanarRotate')">
+
@@ -210,6 +220,7 @@ export default {
activeTool: '',
imageType: ['image/jpeg', 'image/jpg', 'image/bmp', 'image/png'],
loading: false,
+ isFitToWindowMode: false,
trialId: null,
activeName: '1',
tools: [],
@@ -257,7 +268,8 @@ export default {
oldB: null,
oldM: null,
isMove: false,
- height: 0
+ height: 0,
+ zoomText: ''
}))
this.initLoader()
this.$refs['viewports-wrapper'].addEventListener('wheel', (e) => {
@@ -452,6 +464,9 @@ export default {
const renderingEngine = getRenderingEngine(renderingEngineId)
if (renderingEngine) {
renderingEngine.resize(true, false)
+ this.$nextTick(() => {
+ this.reapplyFitModeForVisibleViewports()
+ })
}
})
const element1 = this.$refs['canvas-0'][0]
@@ -468,6 +483,7 @@ export default {
element.oncontextmenu = (e) => e.preventDefault()
resizeObserver.observe(element)
element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
+ element.addEventListener('CORNERSTONE_IMAGE_RENDERED', this.handleImageRendered)
})
const viewportInputArray = [
{
@@ -558,16 +574,57 @@ export default {
const { detail } = e
const i = this.viewportInfos.findIndex(i => i.viewportId === detail.viewportId)
if (i === -1) return
- this.viewportInfos[i].currentImageIdIndex = detail.imageIdIndex
- const obj = this.viewportInfos[i].fileList[detail.imageIdIndex]
- if (!obj) return
- this.viewportInfos[i].currentFileName = obj.FileName
- const total = this.viewportInfos[i].imageIds.length
- this.viewportInfos[i].height = total > 1 ? (this.viewportInfos[i].currentImageIdIndex) * 100 / (total - 1) : 0
- this.$emit('toggleImage', {
- studyId: this.viewportInfos[i].studyId,
- path: obj.Path
- })
+ if (detail.imageIdIndex !== this.viewportInfos[i].currentImageIdIndex) {
+ this.viewportInfos[i].currentImageIdIndex = detail.imageIdIndex
+ const obj = this.viewportInfos[i].fileList[detail.imageIdIndex]
+ if (!obj) return
+ this.viewportInfos[i].currentFileName = obj.FileName
+ const total = this.viewportInfos[i].imageIds.length
+ this.viewportInfos[i].height = total > 1 ? (this.viewportInfos[i].currentImageIdIndex) * 100 / (total - 1) : 0
+ this.$emit('toggleImage', {
+ studyId: this.viewportInfos[i].studyId,
+ path: obj.Path
+ })
+ this.$nextTick(() => {
+ this.applyFitMode(i, this.isFitToWindowMode)
+ })
+ return
+ }
+ this.updateZoomDisplayByViewportId(detail.viewportId)
+ },
+ handleImageRendered(e) {
+ const viewportId = e?.detail?.viewportId || e?.currentTarget?.dataset?.viewportUid
+ if (!viewportId) return
+ this.updateZoomDisplayByViewportId(viewportId)
+ },
+ updateZoomDisplayByViewportId(viewportId) {
+ const index = this.viewportInfos.findIndex(item => item.viewportId === viewportId)
+ if (index === -1) return
+ this.updateZoomDisplay(index)
+ },
+ updateZoomDisplay(index) {
+ const viewportInfo = this.viewportInfos[index]
+ if (!viewportInfo || !this.imageType.includes(viewportInfo.fileType) || !viewportInfo.imageIds.length) {
+ if (viewportInfo) viewportInfo.zoomText = ''
+ return
+ }
+ const renderingEngine = getRenderingEngine(renderingEngineId)
+ const viewport = renderingEngine?.getViewport(viewportInfo.viewportId)
+ if (!viewport) return
+ const camera = viewport.getCamera?.()
+ const canvas = viewport.getCanvas?.() || this.$refs[`canvas-${index}`]?.[0]
+ const canvasHeight = canvas?.clientHeight
+ const parallelScale = Number(camera?.parallelScale)
+ if (!canvasHeight || !Number.isFinite(parallelScale) || parallelScale <= 0) {
+ viewportInfo.zoomText = ''
+ return
+ }
+ const magnification = canvasHeight / (parallelScale * 2)
+ if (!Number.isFinite(magnification) || magnification <= 0) {
+ viewportInfo.zoomText = ''
+ return
+ }
+ viewportInfo.zoomText = `${magnification.toFixed(1)}x`
},
// 渲染图片
async renderImage(imageIds, canvasIndex, sliceIndex) {
@@ -578,6 +635,10 @@ export default {
this.setToolsPassive()
viewport.setImageIdIndex(sliceIndex)
viewport.render()
+ this.$nextTick(() => {
+ this.applyFitMode(canvasIndex, this.isFitToWindowMode)
+ this.updateZoomDisplay(canvasIndex)
+ })
// this.updateViewportInfos()
},
setActiveCanvasImages(obj) {
@@ -636,6 +697,7 @@ export default {
})
} else {
this.viewportInfos[i].currentFilePath = obj.fileInfo.Path
+ this.viewportInfos[i].zoomText = ''
}
},
// 切换图片
@@ -718,6 +780,52 @@ export default {
const viewport = (renderingEngine.getViewport(viewportId))
viewport.resetCamera({ resetPan: true, resetZoom: true, resetToCenter: true })
renderingEngine.render()
+ this.updateZoomDisplay(this.activeCanvasIndex)
+ },
+ toggleFitMode() {
+ this.setToolsPassive()
+ this.isFitToWindowMode = !this.isFitToWindowMode
+ this.applyFitMode(this.activeCanvasIndex, this.isFitToWindowMode)
+ },
+ applyFitMode(canvasIndex = this.activeCanvasIndex, isFitToWindowMode = this.isFitToWindowMode) {
+ const viewportInfo = this.viewportInfos[canvasIndex]
+ if (!viewportInfo || !this.imageType.includes(viewportInfo.fileType) || !viewportInfo.imageIds.length) return
+ const renderingEngine = getRenderingEngine(renderingEngineId)
+ const viewport = renderingEngine?.getViewport(`canvas-${canvasIndex}`)
+ if (!viewport) return
+
+ viewport.resetCamera({ resetPan: true, resetZoom: true, resetToCenter: true })
+ if (isFitToWindowMode) {
+ viewport.render()
+ return
+ }
+
+ const canvas = viewport.getCanvas() || this.$refs[`canvas-${canvasIndex}`]?.[0]
+ const imageData = viewport.getImageData?.()?.imageData
+ const dimensions = imageData?.getDimensions?.()
+ const imageWidth = dimensions?.[0]
+ const imageHeight = dimensions?.[1]
+ const canvasWidth = canvas?.clientWidth
+ const canvasHeight = canvas?.clientHeight
+
+ if (!imageWidth || !imageHeight || !canvasWidth || !canvasHeight) {
+ viewport.render()
+ return
+ }
+
+ const fitScale = Math.min(canvasWidth / imageWidth, canvasHeight / imageHeight)
+ if (fitScale > 0) {
+ viewport.setZoom(1 / fitScale)
+ }
+ viewport.render()
+ this.updateZoomDisplay(canvasIndex)
+ },
+ reapplyFitModeForVisibleViewports() {
+ this.viewportInfos.forEach((viewportInfo, index) => {
+ if (index >= this.cells.length) return
+ if (!this.imageType.includes(viewportInfo.fileType) || !viewportInfo.imageIds.length) return
+ this.applyFitMode(index, this.isFitToWindowMode)
+ })
},
setZoomScale(isZoomIn) {
this.setToolsPassive()
@@ -733,6 +841,7 @@ export default {
const parallelScale = Math.max(0.0001, Math.min(1000000, next))
viewport.setCamera({ parallelScale })
viewport.render()
+ this.updateZoomDisplay(this.activeCanvasIndex)
},
// 滚动条
clickSlider(e, index) {
@@ -753,6 +862,7 @@ export default {
this.setToolsPassive()
viewport.setImageIdIndex(sliceIdx)
viewport.render()
+ this.updateZoomDisplay(index)
},
sliderMouseup(e, index) {
const i = this.viewportInfos.findIndex(i => i.index === index)
@@ -781,6 +891,7 @@ export default {
this.setToolsPassive()
viewport.setImageIdIndex(sliceIdx)
viewport.render()
+ this.updateZoomDisplay(index)
// }
// this.$emit('toggleImage', { taskId: this.viewportInfos[i].taskInfo.VisitTaskId, studyId: this.viewportInfos[i].studyId, imageIndex: sliceIdx })
},
@@ -983,7 +1094,7 @@ export default {
top: 5px;
color: #ddd;
z-index: 1;
- font-size: 12px;
+ font-size: 14px;
.cd-info {
color: #ddd;
@@ -997,6 +1108,15 @@ export default {
}
}
+ .left-bottom-text {
+ position: absolute;
+ left: 5px;
+ bottom: 5px;
+ color: #ddd;
+ z-index: 1;
+ font-size: 14px;
+ }
+
.top-center-tool {
position: absolute;
left: 50%;
diff --git a/src/views/none-dicoms/components/study-list.vue b/src/views/none-dicoms/components/study-list.vue
index 52fa8531..faa24706 100644
--- a/src/views/none-dicoms/components/study-list.vue
+++ b/src/views/none-dicoms/components/study-list.vue
@@ -407,6 +407,9 @@ export default {
color: #ccc;
font-size: 12px;
}
+ ::v-deep .el-switch__label {
+ color: #ccc;
+ }
.file-list-container {
width: 100%;