非dicom图像质控视口信息更改;添加适应窗口、适应图像功能
continuous-integration/drone/push Build is passing Details

rj
caiyiling 2026-07-01 16:59:24 +08:00
parent 0bbf537ddf
commit 4709125107
2 changed files with 135 additions and 12 deletions

View File

@ -11,6 +11,10 @@
<div v-show="imageType.includes(v.fileType)" :ref="`canvas-${index}`" class="content">
<div class="left-top-text">
<div v-if="v.currentFileName">{{ v.currentFileName }}</div>
<div v-if="v.imageIds.length > 0">{{ `${ v.currentImageIdIndex + 1 } / ${ v.imageIds.length }` }}</div>
</div>
<div class="left-bottom-text">
<div v-if="v.zoomText">{{ `Zoom: ${v.zoomText}` }}</div>
</div>
<div :ref="`sliderBox-${index}`" class="right-slider-box" @click.stop="clickSlider($event, index)">
<div :style="{ top: v.height + '%' }" class="slider" @click.stop.prevent="() => { return }"
@ -107,6 +111,12 @@
@click="setToolActive('PlanarRotate')">
<svg-icon icon-class="rotate" style="font-size:20px;" />
</button>
<button
:title="isFitToWindowMode ? $t('trials:reading:button:fitImage') : $t('trials:reading:button:fitWindow')"
class="btn-link" @click="toggleFitMode">
<svg-icon v-if="isFitToWindowMode" icon-class="fitToImage" style="font-size:20px;" />
<svg-icon v-else icon-class="fitToWindow" style="font-size:20px;" />
</button>
<button :title="$t('trials:reading:button:reset')" class="btn-link" @click="resetViewport">
<svg-icon icon-class="refresh" style="font-size:20px;" />
</button>
@ -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%;

View File

@ -407,6 +407,9 @@ export default {
color: #ccc;
font-size: 12px;
}
::v-deep .el-switch__label {
color: #ccc;
}
.file-list-container {
width: 100%;