影像浏览工具增加患者信息
continuous-integration/drone/push Build is running
Details
continuous-integration/drone/push Build is running
Details
parent
d7528de91d
commit
b336e048d7
|
@ -1,15 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div id="canvas" ref="canvas" v-loading="loading" element-loading-text="Loading..."
|
||||||
id="canvas"
|
element-loading-background="rgba(0, 0, 0, 0.8)" style="width:100%;height:100%;position:relative;"
|
||||||
ref="canvas"
|
class="cornerstone-element" @contextmenu.prevent="onContextmenu" @mouseup="sliderMouseup">
|
||||||
v-loading="loading"
|
|
||||||
element-loading-text="Loading..."
|
|
||||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
|
||||||
style="width:100%;height:100%;position:relative;"
|
|
||||||
class="cornerstone-element"
|
|
||||||
@contextmenu.prevent="onContextmenu"
|
|
||||||
@mouseup="sliderMouseup"
|
|
||||||
>
|
|
||||||
<div v-show="dicomInfo.series" class="info-series">
|
<div v-show="dicomInfo.series" class="info-series">
|
||||||
<div>Series #{{ dicomInfo.series }}</div>
|
<div>Series #{{ dicomInfo.series }}</div>
|
||||||
<div>Image #{{ dicomInfo.frame }}</div>
|
<div>Image #{{ dicomInfo.frame }}</div>
|
||||||
|
@ -26,9 +18,11 @@
|
||||||
<div v-show="dicomInfo.location">Location {{ dicomInfo.location }}mm</div> -->
|
<div v-show="dicomInfo.location">Location {{ dicomInfo.location }}mm</div> -->
|
||||||
<!-- <div v-show="toolState.clipPlaying">FPS {{ dicomInfo.fps }}</div> -->
|
<!-- <div v-show="toolState.clipPlaying">FPS {{ dicomInfo.fps }}</div> -->
|
||||||
<div v-show="mousePosition.mo">
|
<div v-show="mousePosition.mo">
|
||||||
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
|
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) :
|
||||||
|
'' }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
<div
|
||||||
|
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||||
HU: {{ mousePosition.mo }}
|
HU: {{ mousePosition.mo }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
||||||
|
@ -46,15 +40,20 @@
|
||||||
|
|
||||||
<div class="info-subject">
|
<div class="info-subject">
|
||||||
<div>{{ stack.description }}</div>
|
<div>{{ stack.description }}</div>
|
||||||
<!-- <div>{{ dicomInfo.hospital }}</div> -->
|
<div v-if="dicomInfo.pid">{{ dicomInfo.pid }}</div>
|
||||||
<!-- <div v-show="dicomInfo.pid">{{ dicomInfo.pid }}</div> -->
|
<div v-if="dicomInfo.patientName">{{ dicomInfo.patientName }}</div>
|
||||||
<!-- <div>{{ dicomInfo.name }}</div> -->
|
<!-- <div>{{ subjectCode }}</div> -->
|
||||||
<!-- <div>{{ dicomInfo.sex }} {{ dicomInfo.age }}</div> -->
|
<!-- <div>{{ dicomInfo.sex }} {{ dicomInfo.age }}</div> -->
|
||||||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
<div v-if="dicomInfo.modality">{{ dicomInfo.modality }}</div>
|
||||||
|
<div v-if="dicomInfo.time">{{ dicomInfo.time }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
<div ref="sliderBox" class="my_slider_box"
|
||||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @mousedown="sliderMousedown($event)" />
|
style="position: absolute;right: 1px;height: calc(100% - 100px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer"
|
||||||
|
@click.stop="goViewer($event)">
|
||||||
|
<div :style="{ top: height + '%' }"
|
||||||
|
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||||||
|
@mousedown="sliderMousedown($event)" />
|
||||||
</div>
|
</div>
|
||||||
<div style="position: absolute;left: 50%;top: 15px;color: #f44336;">
|
<div style="position: absolute;left: 50%;top: 15px;color: #f44336;">
|
||||||
{{ markers.top }}
|
{{ markers.top }}
|
||||||
|
@ -81,15 +80,8 @@
|
||||||
<!-- <div v-show="stack.firstImageLoading" class="load-indicator">
|
<!-- <div v-show="stack.firstImageLoading" class="load-indicator">
|
||||||
Loading Series #{{ stack.seriesNumber }}...
|
Loading Series #{{ stack.seriesNumber }}...
|
||||||
</div>-->
|
</div>-->
|
||||||
<el-dialog
|
<el-dialog v-if="dcmTag.visible" :visible.sync="dcmTag.visible" :close-on-click-modal="false" :title="dcmTag.title"
|
||||||
v-if="dcmTag.visible"
|
width="1000px" custom-class="base-dialog-wrapper" append-to-body>
|
||||||
:visible.sync="dcmTag.visible"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:title="dcmTag.title"
|
|
||||||
width="1000px"
|
|
||||||
custom-class="base-dialog-wrapper"
|
|
||||||
append-to-body
|
|
||||||
>
|
|
||||||
<DicomTags :image-id="stack.imageIds[stack.currentImageIdIndex]" @close="dcmTag.visible = false" />
|
<DicomTags :image-id="stack.imageIds[stack.currentImageIdIndex]" @close="dcmTag.visible = false" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,7 +96,7 @@ const scroll = cornerstoneTools.import('util/scrollToIndex')
|
||||||
import Hammer from 'hammerjs'
|
import Hammer from 'hammerjs'
|
||||||
import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString'
|
import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString'
|
||||||
import invertOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/invertOrientationString'
|
import invertOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/invertOrientationString'
|
||||||
|
import { convertBytes } from '@/utils/dicom-character-set'
|
||||||
import calculateSUV from '@/views/trials/trials-panel/reading/dicoms/tools/calculateSUV'
|
import calculateSUV from '@/views/trials/trials-panel/reading/dicoms/tools/calculateSUV'
|
||||||
// import requestPoolManager from '@/utils/request-pool'
|
// import requestPoolManager from '@/utils/request-pool'
|
||||||
import ScaleOverlayTool from '@/views/trials/trials-panel/reading/dicoms/tools/ScaleOverlay/ScaleOverlayTool'
|
import ScaleOverlayTool from '@/views/trials/trials-panel/reading/dicoms/tools/ScaleOverlay/ScaleOverlayTool'
|
||||||
|
@ -263,9 +255,9 @@ export default {
|
||||||
)
|
)
|
||||||
if (!toolAlreadyAddedToElement) {
|
if (!toolAlreadyAddedToElement) {
|
||||||
if (toolName === 'RectangleRoi') {
|
if (toolName === 'RectangleRoi') {
|
||||||
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true, showStatsText: true}})
|
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true, showStatsText: true } })
|
||||||
} else if (toolName === 'EllipticalRoi') {
|
} else if (toolName === 'EllipticalRoi') {
|
||||||
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true}})
|
cornerstoneTools.addToolForElement(element, apiTool, { configuration: { showMinMax: true } })
|
||||||
} else {
|
} else {
|
||||||
cornerstoneTools.addToolForElement(element, apiTool)
|
cornerstoneTools.addToolForElement(element, apiTool)
|
||||||
}
|
}
|
||||||
|
@ -313,39 +305,14 @@ export default {
|
||||||
}
|
}
|
||||||
cornerstoneTools.setToolActiveForElement(element, 'ScaleOverlay', {})
|
cornerstoneTools.setToolActiveForElement(element, 'ScaleOverlay', {})
|
||||||
}
|
}
|
||||||
// if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.OrientationMarkersTool)) {
|
|
||||||
// cornerstoneTools.addToolForElement(
|
|
||||||
// element,
|
|
||||||
// cornerstoneTools.OrientationMarkersTool
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// cornerstoneTools.setToolActiveForElement(
|
|
||||||
// element,
|
|
||||||
// 'OrientationMarkers',
|
|
||||||
// {}
|
|
||||||
// )
|
|
||||||
cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'playClip'])
|
cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'playClip'])
|
||||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
|
||||||
cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
|
cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
|
||||||
// cornerstoneTools.stackPrefetch.enable(this.canvas)
|
cornerstone.updateImage(element, true)
|
||||||
cornerstone.updateImage(element, true)
|
|
||||||
// cornerstoneTools.stackPrefetch.setConfiguration({ maxImagesToPrefetch: Infinity,
|
|
||||||
// preserveExistingPool: true })
|
|
||||||
// cornerstoneTools.stackPrefetch.enable(this.canvas)
|
|
||||||
// this.stack.imageIds.forEach((item, index) => {
|
|
||||||
// if (index === 0) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// cornerstone.loadImage(item)
|
|
||||||
// })
|
|
||||||
|
|
||||||
this.stack.firstImageLoading = false
|
this.stack.firstImageLoading = false
|
||||||
this.toolState.dicomInfoVisible = true
|
this.toolState.dicomInfoVisible = true
|
||||||
// 重绘历史标记
|
|
||||||
// if (ToolStateManager.toolState.hasOwnProperty(image.imageId) === true) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// this.stack.instanceId = image.imageId.split('/')[image.imageId.split('/').length - 1]
|
|
||||||
var instanceId = image.imageId.split('/')[image.imageId.split('/').length - 1]
|
var instanceId = image.imageId.split('/')[image.imageId.split('/').length - 1]
|
||||||
instanceId = instanceId.split('.')[0]
|
instanceId = instanceId.split('.')[0]
|
||||||
this.stack.instanceId = instanceId
|
this.stack.instanceId = instanceId
|
||||||
|
@ -355,25 +322,36 @@ export default {
|
||||||
onNewImage(e) {
|
onNewImage(e) {
|
||||||
e.detail.enabledElement.options = {}
|
e.detail.enabledElement.options = {}
|
||||||
var data = e.detail.image.data
|
var data = e.detail.image.data
|
||||||
|
const patientNameElement = data.elements.x00100010
|
||||||
|
const patientNameBytes = new Uint8Array(
|
||||||
|
data.byteArray.buffer,
|
||||||
|
patientNameElement ? patientNameElement.dataOffset : 0,
|
||||||
|
patientNameElement ? patientNameElement.length : 0
|
||||||
|
)
|
||||||
|
// 解析dicom中字符集字段与解析库不一致 2025.03.04
|
||||||
|
let SpecificCharacterSet = data.string('x00080005')
|
||||||
|
? data.string('x00080005').replace('ISO IR', 'ISO_IR')
|
||||||
|
: ''
|
||||||
|
const patientNameStr = convertBytes(
|
||||||
|
SpecificCharacterSet,
|
||||||
|
patientNameBytes
|
||||||
|
)
|
||||||
this.dicomInfo.hospital = data.string('x00080080')
|
this.dicomInfo.hospital = data.string('x00080080')
|
||||||
// this.dicomInfo.pid = data.string('x00100020')
|
this.dicomInfo.pid = data.string('x00100020')
|
||||||
this.dicomInfo.pid = data.string('x00120040')
|
this.dicomInfo.patientName = patientNameStr
|
||||||
this.dicomInfo.name = data.string('x00100010')
|
this.dicomInfo.name = data.string('x00100010')
|
||||||
this.dicomInfo.age = data.string('x00101010')
|
this.dicomInfo.age = data.string('x00101010')
|
||||||
this.dicomInfo.sex = data.string('x00100040')
|
this.dicomInfo.sex = data.string('x00100040')
|
||||||
this.dicomInfo.acc = data.string('x00080050') // 登记号
|
this.dicomInfo.acc = data.string('x00080050')
|
||||||
this.dicomInfo.modality = data.string('x00080060')
|
this.dicomInfo.modality = data.string('x00080060')
|
||||||
this.dicomInfo.time = this.formatDicomDateTime(
|
this.dicomInfo.time = this.formatDicomDateTime(
|
||||||
data.string('x00080020'),
|
data.string('x00080020'),
|
||||||
data.string('x00080030')
|
data.string('x00080030')
|
||||||
)
|
)
|
||||||
this.dicomInfo.series = data.string('x00200011')
|
this.dicomInfo.series = data.string('x00200011')
|
||||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
|
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length}`
|
||||||
this.stack.imageIds.length
|
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16('x00280010')}`
|
||||||
}`
|
console.log(this.dicomInfo, 'this.dicomInfo')
|
||||||
this.dicomInfo.size = `${data.uint16('x00280011')}x${data.uint16(
|
|
||||||
'x00280010'
|
|
||||||
)}`
|
|
||||||
var pixel = data.floatString('x00280030')
|
var pixel = data.floatString('x00280030')
|
||||||
if (pixel) {
|
if (pixel) {
|
||||||
this.dicomInfo.pixel = pixel.toFixed(2)
|
this.dicomInfo.pixel = pixel.toFixed(2)
|
||||||
|
@ -1135,6 +1113,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
/* z-index: 1; */
|
/* z-index: 1; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-image {
|
.info-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
|
@ -1154,6 +1133,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
/* z-index: 1; */
|
/* z-index: 1; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-instance {
|
.info-instance {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
|
@ -1186,6 +1166,7 @@ export default {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu__item:hover {
|
.menu__item:hover {
|
||||||
color: #ff0000;
|
color: #ff0000;
|
||||||
}
|
}
|
||||||
|
@ -1205,7 +1186,8 @@ li:hover {
|
||||||
background-color: #e0e0e2;
|
background-color: #e0e0e2;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.my_slider_box:after{
|
|
||||||
|
.my_slider_box:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -20px;
|
bottom: -20px;
|
||||||
|
|
Loading…
Reference in New Issue