1395 lines
45 KiB
Vue
1395 lines
45 KiB
Vue
<template>
|
||
<div id="canvas" ref="canvas" v-loading="loading" :element-loading-text="NSTip"
|
||
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>Series #{{ dicomInfo.series }}</div>
|
||
<div>Image #{{ dicomInfo.frame }}</div>
|
||
<div>{{ dicomInfo.modality }}</div>
|
||
<div v-if="isComparison" style="font-size: 30px;color: #428bca;">{{ tip }}</div>
|
||
</div>
|
||
<div v-show="dicomInfo.series" class="info-image">
|
||
<!-- <div>
|
||
P {{ dicomInfo.size }}
|
||
<span v-show="dicomInfo.pixel">{{ dicomInfo.pixel }}mm</span>
|
||
</div>
|
||
<div v-show="dicomInfo.thick">Slice Thickness {{ dicomInfo.thick }}mm</div>
|
||
<div>WW/WC {{ dicomInfo.wwwc }}</div>
|
||
<div>Zoom {{ dicomInfo.zoom }}</div>
|
||
<div v-show="dicomInfo.location">Location {{ dicomInfo.location }}mm</div>-->
|
||
<!-- <div v-show="toolState.clipPlaying">FPS {{ dicomInfo.fps }}</div> -->
|
||
<div v-show="mousePosition.mo">
|
||
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) :
|
||
'' }}
|
||
</div>
|
||
<div
|
||
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||
HU: {{ mousePosition.mo }}</div>
|
||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">SUVbw(g/ml): {{ mousePosition.suv.toFixed(3)
|
||
}}</div>
|
||
<div v-else-if="mousePosition.mo">Density: {{ mousePosition.mo }}</div>
|
||
<div>W*H: {{ dicomInfo.size }}</div>
|
||
|
||
<div>Zoom: {{ dicomInfo.zoom }}</div>
|
||
</div>
|
||
|
||
<div class="info-subject">
|
||
<div v-if="series.subjectCode">{{ series.subjectCode }}</div>
|
||
<div v-if="series.visitName">{{ series.visitName }}</div>
|
||
<div>{{ stack.description }}</div>
|
||
<!-- <div>{{ dicomInfo.hospital }}</div> -->
|
||
<!-- <div v-show="dicomInfo.pid">{{ dicomInfo.pid }}</div> -->
|
||
<!-- <div>{{ dicomInfo.name }}</div> -->
|
||
<!-- <div>{{ dicomInfo.sex }} {{ dicomInfo.age }}</div> -->
|
||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||
<!-- <div>{{ dicomInfo.time }}</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 :style="{ top: height + '%' }"
|
||
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||
@mousedown="sliderMousedown($event)" />
|
||
</div>
|
||
<div style="position: absolute;left: 50%;top: 15px;color: #f44336;">{{ markers.top }}</div>
|
||
<div style="position: absolute;top: 50%;right: 15px;color: #f44336;">{{ markers.right }}</div>
|
||
|
||
<div style="position: absolute;left: 50%;bottom: 15px;color: #f44336;">{{ markers.bottom }}</div>
|
||
<div style="position: absolute;top: 50%;left: 15px;color: #f44336;">{{ markers.left }}</div>
|
||
|
||
<div class="info-instance">
|
||
<svg-icon icon-class="IsMasked" style="font-size:20px;" v-show="dicomInfo.IsMasked" />
|
||
<!-- <div v-show="dicomInfo.pixel">
|
||
Pixel: {{ dicomInfo.pixel }}mm
|
||
</div>-->
|
||
<div v-show="dicomInfo.location">Location: {{ dicomInfo.location }}</div>
|
||
<div v-show="dicomInfo.thick">Slice Thickness: {{ dicomInfo.thick }}mm</div>
|
||
<div v-show="dicomInfo.wwwc">WW/WL: {{ dicomInfo.wwwc }}</div>
|
||
</div>
|
||
<!-- <div v-show="stack.firstImageLoading" class="load-indicator">
|
||
Loading Series #{{ stack.seriesNumber }}...
|
||
</div>-->
|
||
<el-dialog v-if="dcmTag.visible" :visible.sync="dcmTag.visible" :close-on-click-modal="false" :title="dcmTag.title"
|
||
width="1000px" custom-class="base-dialog-wrapper" append-to-body>
|
||
<dicom-tags :image-id="stack.imageIds[stack.currentImageIdIndex]" @close="dcmTag.visible = false" />
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import * as cornerstone from 'cornerstone-core'
|
||
import * as cornerstoneMath from 'cornerstone-math'
|
||
import * as cornerstoneTools from 'cornerstone-tools'
|
||
import metaDataProvider from '@/utils/metaDataProvider'
|
||
|
||
const scroll = cornerstoneTools.import('util/scrollToIndex')
|
||
import Hammer from 'hammerjs'
|
||
import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString'
|
||
import invertOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/invertOrientationString'
|
||
|
||
const calculateSUV = cornerstoneTools.import('util/calculateSUV')
|
||
// import requestPoolManager from '@/utils/request-pool'
|
||
import ScaleOverlayTool from '@/views/trials/trials-panel/reading/dicoms/tools/ScaleOverlay/ScaleOverlayTool'
|
||
import Note_RectangleRoiTool from '@/views/trials/trials-panel/reading/dicoms/tools/RectangleRoi/Note_RectangleRoiTool'
|
||
let isMetaDataProviderAdded = false
|
||
cornerstoneTools.external.cornerstone = cornerstone
|
||
cornerstoneTools.external.Hammer = Hammer
|
||
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
|
||
cornerstoneTools.toolStyle.setToolWidth(2)
|
||
cornerstoneTools.toolColors.setToolColor('rgb(255, 0, 0)')
|
||
cornerstoneTools.toolColors.setActiveColor('rgb(0, 255, 0)')
|
||
// cornerstoneTools.init({ showSVGCursors: true })
|
||
cornerstoneTools.init()
|
||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||
console.log(cornerstoneTools, 'cornerstoneTools')
|
||
import DicomTags from './DicomTags'
|
||
export default {
|
||
name: 'DicomCanvas',
|
||
components: { DicomTags },
|
||
computed: {
|
||
NSTip() {
|
||
return `${this.$store.state.trials.downloadSize}, NS: ${this.$store.state.trials.downloadTip}`
|
||
},
|
||
},
|
||
props: {
|
||
isComparison: {
|
||
type: Boolean,
|
||
default: false
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
canvas: {},
|
||
height: 0,
|
||
stack: {
|
||
seriesId: '',
|
||
instanceId: '',
|
||
seriesNumber: '',
|
||
imageIds: [],
|
||
currentImageIdIndex: 0,
|
||
firstImageLoading: false,
|
||
// preventCache: true
|
||
},
|
||
dicomInfo: {
|
||
hospital: '',
|
||
pid: '',
|
||
name: '',
|
||
sex: '',
|
||
age: '',
|
||
acc: '',
|
||
modality: '',
|
||
time: '',
|
||
series: '',
|
||
frame: '',
|
||
size: '',
|
||
pixel: 0,
|
||
thick: 0,
|
||
wwwc: '',
|
||
zoom: 0,
|
||
location: '',
|
||
fps: 5,
|
||
IsMasked: false
|
||
},
|
||
toolState: {
|
||
initialized: false,
|
||
activeTool: 'none',
|
||
dicomInfoVisible: false,
|
||
clipPlaying: false,
|
||
viewportInvert: false,
|
||
},
|
||
loadImagePromise: null,
|
||
AnnotationSync: null,
|
||
allROIToolData: {},
|
||
type: '',
|
||
series: '',
|
||
ToolStateManager,
|
||
sliderInfo: {
|
||
oldB: null,
|
||
oldM: null,
|
||
isMove: false,
|
||
},
|
||
mousePosition: { x: '', y: '', mo: '' },
|
||
markers: { top: '', right: '', bottom: '', left: '' },
|
||
orientationMarkers: [],
|
||
originalMarkers: [],
|
||
dcmTag: { visible: false, title: this.$t('trials:dicom-tag:title') },
|
||
tip: ''
|
||
}
|
||
},
|
||
|
||
mounted() {
|
||
this.type = this.$router.currentRoute.query.type
|
||
? this.$router.currentRoute.query.type
|
||
: ''
|
||
this.canvas = this.$refs.canvas
|
||
this.canvas.addEventListener('cornerstonenewimage', this.onNewImage)
|
||
this.canvas.addEventListener(
|
||
'cornerstoneimagerendered',
|
||
this.onImageRendered
|
||
)
|
||
this.canvas.addEventListener(
|
||
'cornerstonetoolsclipstopped',
|
||
this.onClipStopped
|
||
)
|
||
this.canvas.addEventListener('mouseleave', () => {
|
||
this.mousePosition.mo = ''
|
||
})
|
||
this.canvas.addEventListener('cornerstonetoolsmousemove', this.mouseMove)
|
||
document.addEventListener('mouseup', () => {
|
||
this.sliderMouseup()
|
||
})
|
||
document.addEventListener('mousemove', (e) => {
|
||
this.sliderMousemove(e)
|
||
})
|
||
this.canvas.addEventListener(
|
||
'cornerstonetoolsstackscroll',
|
||
this.stackScrollCallback
|
||
)
|
||
},
|
||
|
||
methods: {
|
||
loadImageStack(dicomSeries, text = '') {
|
||
this.tip = text
|
||
this.$nextTick(() => {
|
||
if (!dicomSeries || !Array.isArray(dicomSeries.imageIds) || dicomSeries.imageIds.length === 0) {
|
||
return
|
||
}
|
||
this.series = dicomSeries
|
||
this.stack.seriesId = dicomSeries.seriesId
|
||
this.stack.seriesNumber = dicomSeries.seriesNumber
|
||
this.stack.imageIds = dicomSeries.imageIds
|
||
this.stack.currentImageIdIndex =
|
||
dicomSeries.imageIdIndex &&
|
||
dicomSeries.imageIdIndex < dicomSeries.imageIds.length
|
||
? dicomSeries.imageIdIndex
|
||
: 0
|
||
this.stack.firstImageLoading = true
|
||
this.stack.description = dicomSeries.description
|
||
this.toolState.viewportInvert = false
|
||
this.toolState.dicomInfoVisible = false
|
||
// var imageId = this.stack.imageIds[this.stack.currentImageIdIndex]
|
||
// var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||
// instanceId = instanceId.split('.')[0]
|
||
// this.stack.instanceId = instanceId
|
||
this.toolState.clipPlaying = false
|
||
const element = this.$refs.canvas
|
||
if (!isMetaDataProviderAdded) {
|
||
// 注册自定义 metaDataProvider:统一 SUV 口径(优先接口,缺失回退 DICOM)
|
||
cornerstone.metaData.addProvider(metaDataProvider, 100000)
|
||
isMetaDataProviderAdded = true
|
||
}
|
||
cornerstone.enable(element)
|
||
cornerstoneTools.stopClip(this.canvas)
|
||
this.toolState.clipPlaying = false
|
||
this.loading = true
|
||
|
||
cornerstone
|
||
.loadAndCacheImage(
|
||
this.stack.imageIds[this.stack.currentImageIdIndex]
|
||
)
|
||
.then((image) => {
|
||
this.loading = false
|
||
if (this.stack.imageIds.indexOf(image.imageId) !== -1) {
|
||
this.onFirstImageLoaded(image)
|
||
}
|
||
})
|
||
.catch((error) => {
|
||
this.loading = false
|
||
if (error.error && error.error.message) {
|
||
this.$alert(error.error.message)
|
||
}
|
||
})
|
||
})
|
||
},
|
||
onFirstImageLoaded(image) {
|
||
const element = this.$refs.canvas
|
||
var viewport = cornerstone.getDefaultViewportForImage(this.canvas, image)
|
||
cornerstone.displayImage(this.canvas, image, viewport)
|
||
|
||
if (!this.toolState.initialized) {
|
||
this.toolState.initialized = true
|
||
const toolButtons = document.querySelectorAll('[data-tool]')
|
||
// const scope = this
|
||
Array.from(toolButtons).forEach((toolBtn) => {
|
||
// Add the tool
|
||
const toolName = toolBtn.getAttribute('data-tool')
|
||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||
|
||
if (apiTool) {
|
||
const toolAlreadyAddedToElement =
|
||
cornerstoneTools.getToolForElement(element, apiTool)
|
||
if (!toolAlreadyAddedToElement) {
|
||
if (toolName === 'RectangleRoi') {
|
||
cornerstoneTools.addToolForElement(element, apiTool, {
|
||
configuration: { showMinMax: true, showStatsText: true },
|
||
})
|
||
} else if (toolName === 'EllipticalRoi') {
|
||
cornerstoneTools.addToolForElement(element, apiTool, {
|
||
configuration: { showMinMax: true },
|
||
})
|
||
} else {
|
||
cornerstoneTools.addToolForElement(element, apiTool)
|
||
}
|
||
}
|
||
}
|
||
// Setup button listener
|
||
// Prevent right click context menu for our menu buttons
|
||
toolBtn.addEventListener(
|
||
'contextmenu',
|
||
(event) => event.preventDefault(),
|
||
true
|
||
)
|
||
// Prevent middle click opening a new tab on Chrome & FF
|
||
toolBtn.addEventListener(
|
||
'auxclick',
|
||
(event) => {
|
||
if (event.button && event.button === 1) {
|
||
event.preventDefault()
|
||
}
|
||
},
|
||
false
|
||
)
|
||
})
|
||
if (
|
||
!cornerstoneTools.getToolForElement(element, Note_RectangleRoiTool)
|
||
) {
|
||
cornerstoneTools.addToolForElement(element, Note_RectangleRoiTool, {
|
||
configuration: {
|
||
color: '#f00',
|
||
lineWidth: 2,
|
||
drawHandles: false,
|
||
fillColor: 'rgba(0, 0, 0, 1)',
|
||
},
|
||
})
|
||
}
|
||
if (
|
||
!cornerstoneTools.getToolForElement(
|
||
element,
|
||
cornerstoneTools.WwwcRegionTool
|
||
)
|
||
) {
|
||
cornerstoneTools.addToolForElement(
|
||
element,
|
||
cornerstoneTools.WwwcRegionTool
|
||
)
|
||
}
|
||
if (
|
||
!cornerstoneTools.getToolForElement(
|
||
element,
|
||
cornerstoneTools.StackScrollMouseWheelTool
|
||
)
|
||
) {
|
||
cornerstoneTools.addToolForElement(
|
||
element,
|
||
cornerstoneTools.StackScrollMouseWheelTool
|
||
)
|
||
}
|
||
cornerstoneTools.setToolActiveForElement(
|
||
element,
|
||
'StackScrollMouseWheel',
|
||
{}
|
||
)
|
||
if (!cornerstoneTools.getToolForElement(element, ScaleOverlayTool)) {
|
||
cornerstoneTools.addToolForElement(element, ScaleOverlayTool)
|
||
}
|
||
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', 'stackPrefetch', 'playClip'])
|
||
cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
|
||
// cornerstoneTools.stackPrefetch.enable(this.canvas)
|
||
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.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]
|
||
// instanceId = instanceId.split('.')[0]
|
||
// this.stack.instanceId = instanceId
|
||
this.height = this.getStackHeightPercent()
|
||
this.resetWwwc()
|
||
},
|
||
onNewImage(e) {
|
||
e.detail.enabledElement.options = {}
|
||
var data = e.detail.image.data
|
||
this.dicomInfo.hospital = data.string('x00080080')
|
||
// let instanceInfo = this.series.instanceInfoList.find(item => item.ImageId === e.detail.image.imageId)
|
||
let instanceInfo = this.series?.instanceInfoList?.find(item => {
|
||
let s1 = item.ImageId ? item.ImageId.split("?")[0] : ''
|
||
let s2 = e.detail.image.imageId ? e.detail.image.imageId.split("?")[0] : ''
|
||
return s1 === s2
|
||
})
|
||
this.dicomInfo.IsMasked = instanceInfo ? instanceInfo.IsMasked : false
|
||
// this.dicomInfo.pid = data.string('x00100020')
|
||
this.dicomInfo.pid = data.string('x00120040')
|
||
this.dicomInfo.name = data.string('x00100010')
|
||
this.dicomInfo.age = data.string('x00101010')
|
||
this.dicomInfo.sex = data.string('x00100040')
|
||
this.dicomInfo.acc = data.string('x00080050') // 登记号
|
||
this.dicomInfo.modality = (data.string('x00080060') || '').trim()
|
||
this.dicomInfo.time = this.formatDicomDateTime(
|
||
data.string('x00080020'),
|
||
data.string('x00080030')
|
||
)
|
||
this.dicomInfo.series = data.string('x00200011')
|
||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
|
||
}`
|
||
this.dicomInfo.size = `${data.uint16('x00280011')}x${data.uint16(
|
||
'x00280010'
|
||
)}`
|
||
var pixel = data.floatString('x00280030')
|
||
if (pixel) {
|
||
this.dicomInfo.pixel = pixel.toFixed(2)
|
||
}
|
||
this.dicomInfo.thick = data.floatString('x00180050') // 切片厚度
|
||
if (this.dicomInfo.thick) {
|
||
this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
|
||
}
|
||
const newImageIdIndex = this.stack.imageIds.findIndex(
|
||
(i) => i === e.detail.image.imageId
|
||
)
|
||
if (newImageIdIndex === -1) return
|
||
this.stack.currentImageIdIndex = newImageIdIndex
|
||
this.stack.imageIdIndex = newImageIdIndex
|
||
this.series.imageIdIndex = newImageIdIndex
|
||
this.height = this.getStackHeightPercent()
|
||
},
|
||
getStackHeightPercent() {
|
||
const imageCount = Array.isArray(this.stack.imageIds) ? this.stack.imageIds.length : 0
|
||
if (imageCount <= 1) {
|
||
return 0
|
||
}
|
||
return (this.stack.currentImageIdIndex * 100) / (imageCount - 1)
|
||
},
|
||
stackScrollCallback(e) {
|
||
const { detail } = e
|
||
if (this.isScrollSync) {
|
||
this.$emit('scrollSync', {
|
||
canvasIndex: this.canvasIndex,
|
||
direction: detail.direction,
|
||
})
|
||
}
|
||
this.stack.currentImageIdIndex = e.detail.newImageIdIndex
|
||
this.height = this.getStackHeightPercent()
|
||
// var priority = new Date(new Date().setHours(23, 59, 59, 999)).getTime()
|
||
|
||
// requestPoolManager.loadAndCacheImagePlus(this.stack.imageIds[this.stack.currentImageIdIndex], this.stack.seriesId, priority)
|
||
// .then(image => {
|
||
// this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
|
||
// })
|
||
// .catch((error) => {
|
||
// console.log(error)
|
||
// })
|
||
},
|
||
formatDicomDateTime(date, time) {
|
||
if (date) {
|
||
date = `${date.substr(0, 4)}-${date.substr(4, 2)}-${date.substr(6, 2)}`
|
||
}
|
||
if (time) {
|
||
time = `${time.substr(0, 2)}:${time.substr(2, 2)}:${time.substr(4, 2)}`
|
||
}
|
||
return time ? `${date} ${time}` : `${date} 00:00:00`
|
||
},
|
||
|
||
onImageRendered(e) {
|
||
// var imageId = e.detail.image.imageId
|
||
// var instanceId = imageId.split('/')[imageId.split('/').length - 1]
|
||
// instanceId = instanceId.split('.')[0]
|
||
|
||
// if (this.imageId !== instanceId) {
|
||
// this.getOrientationMarker(e.detail.element)
|
||
// this.imageId = instanceId
|
||
// }
|
||
this.getOrientationMarker(e.detail.element)
|
||
// this.stack.instanceId = instanceId
|
||
var viewport = e.detail.viewport
|
||
this.dicomInfo.wwwc = `${Math.round(
|
||
viewport.voi.windowWidth
|
||
)}/${Math.round(viewport.voi.windowCenter)}` // 窗位
|
||
// this.dicomInfo.zoom = viewport.scale.toFixed(2)
|
||
this.dicomInfo.zoom = viewport.scale.toFixed(4)
|
||
var data = e.detail.image.data
|
||
const position = data.string('x00201041')
|
||
this.dicomInfo.location = position
|
||
},
|
||
getOrientationMarker(element) {
|
||
console.log('getOrientationMarker')
|
||
const enabledElement = cornerstone.getEnabledElement(element)
|
||
const imagePlane = cornerstone.metaData.get(
|
||
'imagePlaneModule',
|
||
enabledElement.image.imageId
|
||
)
|
||
|
||
if (!imagePlane || !imagePlane.rowCosines || !imagePlane.columnCosines) {
|
||
return
|
||
}
|
||
|
||
const row = getOrientationString(imagePlane.rowCosines)
|
||
const column = getOrientationString(imagePlane.columnCosines)
|
||
const oppositeRow = invertOrientationString(row)
|
||
const oppositeColumn = invertOrientationString(column)
|
||
const markers = {
|
||
top: oppositeColumn,
|
||
bottom: column,
|
||
left: oppositeRow,
|
||
right: row,
|
||
}
|
||
if (!markers) {
|
||
return
|
||
}
|
||
|
||
this.orientationMarkers = [oppositeColumn, row, column, oppositeRow]
|
||
this.originalMarkers = [oppositeColumn, row, column, oppositeRow]
|
||
this.setMarkers()
|
||
},
|
||
setMarkers() {
|
||
var markers = [...this.orientationMarkers]
|
||
for (const key in this.markers) {
|
||
var v = markers.shift(0)
|
||
this.markers[key] = v
|
||
}
|
||
},
|
||
onImageLoaded(e) {
|
||
// var image = e.detail.image
|
||
// // var seriesIndex = -1
|
||
// var seriesUid = image.data.string('x0020000e')
|
||
// console.log(seriesUid)
|
||
},
|
||
getToolForElement(toolName) {
|
||
var isExist = false
|
||
for (var i = 0; i < cornerstoneTools.store.state.tools.length; i++) {
|
||
if (cornerstoneTools.store.state.tools[i].name === toolName) {
|
||
isExist = true
|
||
break
|
||
}
|
||
}
|
||
return isExist
|
||
},
|
||
mouseMove(e) {
|
||
const { element, image, currentPoints } = e.detail
|
||
const x = Math.round(currentPoints.image.x)
|
||
const y = Math.round(currentPoints.image.y)
|
||
|
||
const stats = {}
|
||
|
||
if (x >= 0 && y >= 0 && x < image.columns && y < image.rows) {
|
||
stats.x = x
|
||
stats.y = y
|
||
|
||
if (image.color) {
|
||
stats.storedPixels = this.getRGBPixels(element, x, y, 1, 1)
|
||
} else {
|
||
stats.storedPixels = cornerstone.getStoredPixels(element, x, y, 1, 1)
|
||
stats.sp = stats.storedPixels[0]
|
||
stats.mo = stats.sp * image.slope + image.intercept
|
||
stats.suv = calculateSUV(image, stats.sp)
|
||
}
|
||
}
|
||
|
||
this.mousePosition.x = currentPoints.image.x + 1
|
||
this.mousePosition.y = currentPoints.image.y + 1
|
||
this.mousePosition.mo = stats.mo
|
||
this.mousePosition.suv = stats.suv
|
||
},
|
||
getRGBPixels(element, x, y, width, height) {
|
||
if (!element) {
|
||
return
|
||
}
|
||
x = Math.round(x)
|
||
y = Math.round(y)
|
||
const enabledElement = cornerstone.getEnabledElement(element)
|
||
const storedPixelData = []
|
||
let index = 0
|
||
const pixelData = enabledElement.image.getPixelData()
|
||
let spIndex, row, column
|
||
|
||
if (enabledElement.image.color) {
|
||
for (row = 0; row < height; row++) {
|
||
for (column = 0; column < width; column++) {
|
||
spIndex =
|
||
((row + y) * enabledElement.image.columns + (column + x)) * 4
|
||
const red = pixelData[spIndex]
|
||
const green = pixelData[spIndex + 1]
|
||
const blue = pixelData[spIndex + 2]
|
||
const alpha = pixelData[spIndex + 3]
|
||
|
||
storedPixelData[index++] = red
|
||
storedPixelData[index++] = green
|
||
storedPixelData[index++] = blue
|
||
storedPixelData[index++] = alpha
|
||
}
|
||
}
|
||
}
|
||
|
||
return storedPixelData
|
||
},
|
||
sliderMousedown(e) {
|
||
var boxHeight = this.$refs['sliderBox'].clientHeight
|
||
this.sliderInfo.oldB =
|
||
(parseInt(e.srcElement.style.top) * boxHeight) / 100
|
||
this.sliderInfo.oldM = e.clientY
|
||
this.sliderInfo.isMove = true
|
||
e.stopImmediatePropagation()
|
||
e.stopPropagation()
|
||
e.preventDefault()
|
||
},
|
||
sliderMousemove(e) {
|
||
if (!this.sliderInfo.isMove) return
|
||
var PX = this.sliderInfo.oldB - (this.sliderInfo.oldM - e.clientY)
|
||
var boxHeight = this.$refs['sliderBox'].clientHeight
|
||
if (PX < 0) return
|
||
if (PX > boxHeight) return
|
||
var height = (PX * 100) / boxHeight
|
||
var index = Math.trunc((this.stack.imageIds.length * this.height) / 100)
|
||
index =
|
||
index > this.stack.imageIds.length
|
||
? this.stack.imageIds.length
|
||
: index < 0
|
||
? 0
|
||
: index
|
||
// if (!cornerstone.imageCache.getImageLoadObject(this.stack.imageIds[index])) return
|
||
this.height = height
|
||
if (this.stack.currentImageIdIndex !== index) {
|
||
scroll(this.canvas, index)
|
||
}
|
||
},
|
||
sliderMouseup(e) {
|
||
this.sliderInfo.isMove = false
|
||
},
|
||
goViewer(e) {
|
||
// console.log(this.$refs['sliderBox'].clientHeight)
|
||
var height = (e.offsetY * 100) / this.$refs['sliderBox'].clientHeight
|
||
this.height = height
|
||
var index = Math.trunc((this.stack.imageIds.length * this.height) / 100)
|
||
scroll(this.canvas, index)
|
||
},
|
||
onClipStopped() {
|
||
this.toolState.clipPlaying = false
|
||
},
|
||
|
||
onKeyPress(e) {
|
||
var key = e.detail.keyCode
|
||
var keys = { PageUp: 33, PageDown: 34, End: 35, Home: 36 } // Left: 37, Up: 38, Right: 39, Down: 40
|
||
if (key < keys.PageUp || key > keys.Home) return
|
||
if (key === keys.Home) this.scrollPage(-9999)
|
||
else if (key === keys.PageUp) this.scrollPage(-1)
|
||
else if (key === keys.PageDown) this.scrollPage(1)
|
||
else if (key === keys.End) this.scrollPage(9999)
|
||
},
|
||
|
||
resizeCanvas() {
|
||
cornerstone.resize(this.canvas, true)
|
||
},
|
||
|
||
activateCanvas() {
|
||
this.canvas.tabIndex = 0
|
||
this.canvas.focus()
|
||
},
|
||
|
||
resetViewport() {
|
||
this.toolState.viewportInvert = false
|
||
var image = cornerstone.getImage(this.canvas)
|
||
cornerstone.setViewport(
|
||
this.canvas,
|
||
cornerstone.getDefaultViewportForImage(this.canvas, image)
|
||
)
|
||
},
|
||
|
||
toggleDicomInfo() {
|
||
this.toolState.dicomInfoVisible = !this.toolState.dicomInfoVisible
|
||
if (this.toolState.dicomInfoVisible) {
|
||
cornerstoneTools.orientationMarkers.enable(this.canvas)
|
||
} else cornerstoneTools.orientationMarkers.disable(this.canvas)
|
||
cornerstone.updateImage(this.canvas)
|
||
},
|
||
setColormap(colormap) {
|
||
const viewport = cornerstone.getViewport(this.canvas)
|
||
viewport.colormap = colormap
|
||
cornerstone.setViewport(this.canvas, viewport)
|
||
cornerstone.updateImage(this.canvas, true)
|
||
if (!colormap) {
|
||
this.resetRenderCanvase(this.canvas)
|
||
}
|
||
},
|
||
resetRenderCanvase(element) {
|
||
const enabledElement = cornerstone.getEnabledElement(element)
|
||
|
||
enabledElement.renderingTools.colormapId = undefined
|
||
enabledElement.renderingTools.colorLut = undefined
|
||
|
||
const renderCanvas = enabledElement.renderingTools.renderCanvas
|
||
const canvasContext = renderCanvas.getContext('2d')
|
||
canvasContext.fillStyle = 'white'
|
||
canvasContext.fillRect(0, 0, renderCanvas.width, renderCanvas.height)
|
||
|
||
const renderCanvasData = canvasContext.getImageData(
|
||
0,
|
||
0,
|
||
renderCanvas.width,
|
||
renderCanvas.height
|
||
)
|
||
|
||
enabledElement.renderingTools.renderCanvasContext = canvasContext
|
||
enabledElement.renderingTools.renderCanvasData = renderCanvasData
|
||
},
|
||
scrollPage(offset) {
|
||
if (this.loading) return
|
||
var index = this.stack.currentImageIdIndex + offset
|
||
if (index < 0) index = 0
|
||
else if (index >= this.stack.imageIds.length) {
|
||
index = this.stack.imageIds.length - 1
|
||
}
|
||
if (index !== this.stack.currentImageIdIndex) {
|
||
scroll(this.canvas, index)
|
||
}
|
||
},
|
||
|
||
toggleClipPlay() {
|
||
if (this.loading) return
|
||
if (this.toolState.clipPlaying) {
|
||
cornerstoneTools.stopClip(this.canvas)
|
||
this.toolState.clipPlaying = false
|
||
return
|
||
}
|
||
this.toolState.clipPlaying = true
|
||
cornerstoneTools.playClip(this.canvas, this.dicomInfo.fps)
|
||
cornerstoneTools.getToolState(this.canvas, 'playClip').data[0].loop = true
|
||
},
|
||
setFps(fps) {
|
||
this.dicomInfo.fps = fps
|
||
},
|
||
|
||
resetWwwc() {
|
||
this.toolState.viewportInvert = false
|
||
var viewport = cornerstone.getViewport(this.canvas)
|
||
// viewport.invert = false
|
||
var image = cornerstone.getImage(this.canvas)
|
||
if (!viewport || !image) return
|
||
viewport.voi.windowWidth = image.windowWidth
|
||
viewport.voi.windowCenter = image.windowCenter
|
||
cornerstone.setViewport(this.canvas, viewport)
|
||
},
|
||
|
||
setWwwc(ww, wc) {
|
||
var viewport = cornerstone.getViewport(this.canvas)
|
||
viewport.voi.windowWidth = ww
|
||
viewport.voi.windowCenter = wc
|
||
cornerstone.setViewport(this.canvas, viewport)
|
||
},
|
||
|
||
toggleInvert() {
|
||
this.toolState.viewportInvert = !this.toolState.viewportInvert
|
||
var viewport = cornerstone.getViewport(this.canvas)
|
||
viewport.invert = this.toolState.viewportInvert
|
||
cornerstone.setViewport(this.canvas, viewport)
|
||
},
|
||
|
||
activateZoom() {
|
||
cornerstoneTools.addTool(cornerstoneTools.ZoomTool, {
|
||
configuration: {
|
||
invert: false,
|
||
preventZoomOutsideImage: false,
|
||
minScale: 0.1,
|
||
maxScale: 20.0,
|
||
},
|
||
})
|
||
cornerstoneTools.setToolActive('Zoom', { mouseButtonMask: 1 })
|
||
this.toolState.activeTool = 'zoom'
|
||
},
|
||
|
||
resetRotate() {
|
||
if (this.originalMarkers.length > 0) {
|
||
this.orientationMarkers = [...this.originalMarkers]
|
||
this.setMarkers()
|
||
}
|
||
|
||
var viewport = cornerstone.getViewport(this.canvas)
|
||
viewport.hflip = false
|
||
viewport.vflip = false
|
||
viewport.rotation = 0
|
||
cornerstone.setViewport(this.canvas, viewport)
|
||
},
|
||
|
||
setRotate(hflip, vflip, angle, type) {
|
||
if (this.orientationMarkers.length > 0) {
|
||
var markers = [...this.orientationMarkers]
|
||
if (type === 2) {
|
||
// 垂直翻转
|
||
this.orientationMarkers[1] = markers[3]
|
||
|
||
this.orientationMarkers[3] = markers[1]
|
||
} else if (type === 3) {
|
||
// 水平翻转
|
||
this.orientationMarkers[0] = markers[2]
|
||
this.orientationMarkers[2] = markers[0]
|
||
} else if (type === 4) {
|
||
// 左转90度
|
||
this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
|
||
} else if (type === 5) {
|
||
// 右转90度
|
||
this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
|
||
}
|
||
this.setMarkers()
|
||
}
|
||
var viewport = cornerstone.getViewport(this.canvas)
|
||
if (hflip) viewport.hflip = !viewport.hflip
|
||
if (vflip) viewport.vflip = !viewport.vflip
|
||
if (angle !== 0) viewport.rotation += angle
|
||
cornerstone.setViewport(this.canvas, viewport)
|
||
},
|
||
|
||
saveImage() {
|
||
var uid = cornerstone.getImage(this.canvas).data.string('x00080018')
|
||
cornerstoneTools.SaveAs(this.canvas, `${uid}.png`)
|
||
},
|
||
showTags() {
|
||
this.dcmTag.visible = true
|
||
},
|
||
fitToWindow() {
|
||
if (this.stack.seriesNumber) {
|
||
cornerstone.fitToWindow(this.canvas)
|
||
}
|
||
},
|
||
fitToImage() {
|
||
if (this.stack.seriesNumber) {
|
||
const enabledElement = cornerstone.getEnabledElement(this.canvas)
|
||
enabledElement.viewport.scale = 1
|
||
cornerstone.updateImage(this.canvas)
|
||
}
|
||
},
|
||
clearMeasurement() {
|
||
const viewport = cornerstone.getViewport(this.canvas)
|
||
if (viewport.colormap) {
|
||
this.resetRenderCanvase(this.canvas)
|
||
}
|
||
ToolStateManager.clear(this.canvas)
|
||
cornerstone.setViewport(
|
||
this.canvas,
|
||
cornerstone.getDefaultViewportForImage(
|
||
this.canvas,
|
||
cornerstone.getImage(this.canvas)
|
||
)
|
||
)
|
||
cornerstone.updateImage(this.canvas)
|
||
},
|
||
setToolPassive(toolName) {
|
||
cornerstoneTools.setToolPassiveForElement(this.canvas, toolName)
|
||
},
|
||
async reloadImage(newImageId = null) {
|
||
// 1. 获取当前imageId(如果未指定新imageId)
|
||
let element = this.canvas
|
||
this.stack.imageIds.splice(this.stack.currentImageIdIndex, 1, newImageId)
|
||
const currentImageId =
|
||
newImageId || cornerstone.getImage(element)?.imageId
|
||
|
||
if (!currentImageId) {
|
||
console.error('没有找到可用的imageId')
|
||
return
|
||
}
|
||
|
||
// 2. 清除该影像关联的工具状态(标注数据)
|
||
this.clearToolStateForImage(element, currentImageId)
|
||
|
||
// 3. 从缓存中移除该影像
|
||
this.removeImageFromCache(currentImageId)
|
||
|
||
// 4. 重新加载并渲染
|
||
await this.loadAndRenderImage(element, currentImageId)
|
||
},
|
||
clearToolStateForImage(element, imageId) {
|
||
// 获取全局状态管理器
|
||
const globalToolStateManager =
|
||
cornerstoneTools.globalImageIdSpecificToolStateManager
|
||
|
||
if (globalToolStateManager) {
|
||
// 方式1:清空该影像的全部工具数据
|
||
globalToolStateManager.clearImageIdToolState(imageId)
|
||
console.log(`已清除影像 ${imageId} 的所有标注数据`)
|
||
}
|
||
|
||
// 方式2:如果使用元素级别的状态管理器
|
||
const elementToolStateManager =
|
||
cornerstoneTools.getElementToolStateManager(element)
|
||
if (elementToolStateManager && elementToolStateManager.get(element)) {
|
||
// 清空该元素上当前显示影像的数据
|
||
elementToolStateManager.clear(element)
|
||
}
|
||
},
|
||
removeImageFromCache(imageId) {
|
||
const imageCache = cornerstone.imageCache
|
||
|
||
if (imageCache && imageCache[imageId]) {
|
||
// 从缓存中移除
|
||
delete imageCache[imageId]
|
||
console.log(`已从缓存中移除影像: ${imageId}`)
|
||
}
|
||
|
||
// 也可以使用官方API(如果可用)
|
||
if (typeof cornerstone.imageCache.removeImage === 'function') {
|
||
cornerstone.imageCache.removeImageLoadObject(imageId)
|
||
}
|
||
},
|
||
async loadAndRenderImage(element, imageId) {
|
||
try {
|
||
// 1. 清除当前画布内容(可选)
|
||
const canvas = element.querySelector('canvas')
|
||
if (canvas) {
|
||
const ctx = canvas.getContext('2d')
|
||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||
}
|
||
|
||
// 2. 重新加载图像(强制从源头重新获取)
|
||
const image = await cornerstone.loadAndCacheImage(imageId)
|
||
|
||
// 3. 获取或创建视口设置
|
||
let viewport = cornerstone.getViewport(element)
|
||
if (!viewport) {
|
||
viewport = cornerstone.getDefaultViewport(element, image)
|
||
}
|
||
|
||
// 4. 显示图像
|
||
cornerstone.displayImage(element, image, viewport)
|
||
|
||
// 5. 触发重绘
|
||
cornerstone.updateImage(element)
|
||
|
||
console.log(`影像 ${imageId} 重新加载并渲染完成`)
|
||
|
||
return image
|
||
} catch (error) {
|
||
console.error('加载图像失败:', error)
|
||
throw error
|
||
}
|
||
},
|
||
getNote_RectangleRoi() {
|
||
return new Promise(resolve => {
|
||
let toolInfo = cornerstoneTools.getToolState(this.canvas, 'Note_RectangleRoi')
|
||
let image = cornerstone.getImage(this.canvas)
|
||
resolve({ toolInfo, image })
|
||
})
|
||
// console.log(
|
||
// cornerstoneTools.getToolState(this.canvas, 'Note_RectangleRoi')
|
||
// )
|
||
// console.log(cornerstone.getImage(this.canvas))
|
||
// let image = cornerstone.getImage(this.canvas)
|
||
// // cornerstone.imageCache.removeImageLoadObject(image.imageId)
|
||
|
||
// this.reloadImage(this.canvas, image.imageId)
|
||
},
|
||
removeNote_RectangleRoi() {
|
||
const toolState = cornerstoneTools.getToolState(this.canvas, 'Note_RectangleRoi');
|
||
if (toolState && toolState.data.length > 0) {
|
||
let arr = toolState.data.map(item => item)
|
||
arr.forEach(item => {
|
||
cornerstoneTools.removeToolState(this.canvas, 'Note_RectangleRoi', item);
|
||
})
|
||
cornerstone.updateImage(this.canvas);
|
||
}
|
||
},
|
||
setToolActive(toolName) {
|
||
cornerstoneTools.setToolActiveForElement(this.canvas, toolName, {
|
||
mouseButtonMask: 1,
|
||
})
|
||
},
|
||
setAllToolsPassive() {
|
||
cornerstoneTools.store.state.tools.forEach((tool) => {
|
||
cornerstoneTools.setToolPassiveForElement(this.canvas, tool.name)
|
||
})
|
||
},
|
||
|
||
addTargetElement(synchronizer) {
|
||
synchronizer.addTarget(this.$refs.canvas)
|
||
},
|
||
removeTarget(synchronizer) {
|
||
synchronizer.removeTarget(this.$refs.canvas)
|
||
},
|
||
addSourceElement(synchronizer) {
|
||
synchronizer.addSource(this.$refs.canvas)
|
||
},
|
||
removeSource(synchronizer) {
|
||
synchronizer.removeSource(this.$refs.canvas)
|
||
},
|
||
activeReferenceLine(synchronizer) {
|
||
if (
|
||
!cornerstoneTools.getToolForElement(
|
||
this.canvas,
|
||
cornerstoneTools.ReferenceLinesTool
|
||
)
|
||
) {
|
||
cornerstoneTools.addToolForElement(
|
||
this.canvas,
|
||
cornerstoneTools.ReferenceLinesTool
|
||
)
|
||
}
|
||
cornerstoneTools.setToolEnabledForElement(this.canvas, 'ReferenceLines', {
|
||
synchronizationContext: synchronizer,
|
||
})
|
||
|
||
// cornerstoneTools.addTool(cornerstoneTools.CrosshairsTool)
|
||
// cornerstoneTools.setToolActive('Crosshairs', {
|
||
// mouseButtonMask: 1,
|
||
// synchronizationContext: synchronizer
|
||
// })
|
||
},
|
||
disabledReferenceLine(synchronizer) {
|
||
synchronizer.enabled = false
|
||
synchronizer.remove(this.canvas)
|
||
cornerstoneTools.setToolDisabledForElement(this.canvas, 'ReferenceLines')
|
||
// cornerstoneTools.setToolDisabledForElement(this.canvas, 'Crosshairs')
|
||
},
|
||
activeViewPortToolSync(synchronizer, toolName) {
|
||
synchronizer.add(this.canvas)
|
||
synchronizer.enabled = true
|
||
if (
|
||
!cornerstoneTools.getToolForElement(
|
||
this.canvas,
|
||
cornerstoneTools[`${toolName}Tool`]
|
||
)
|
||
) {
|
||
cornerstoneTools.addToolForElement(
|
||
this.canvas,
|
||
cornerstoneTools[`${toolName}Tool`]
|
||
)
|
||
}
|
||
cornerstoneTools.setToolActiveForElement(this.canvas, toolName, {
|
||
mouseButtonMask: 1,
|
||
synchronizationContext: synchronizer,
|
||
})
|
||
},
|
||
disabledViewPortToolSync(synchronizer, toolName) {
|
||
synchronizer.enabled = false
|
||
synchronizer.remove(this.canvas)
|
||
cornerstoneTools.setToolDisabledForElement(this.canvas, toolName)
|
||
},
|
||
activeImageSync(synchronizer) {
|
||
synchronizer.add(this.$refs.canvas)
|
||
synchronizer.enabled = true
|
||
return false
|
||
},
|
||
disabledImageSync(synchronizer) {
|
||
synchronizer.remove(this.$refs.canvas)
|
||
synchronizer.enabled = false
|
||
return false
|
||
},
|
||
activeAnnotationSync(synchronizer) {
|
||
this.AnnotationSync = synchronizer
|
||
synchronizer.add(this.$refs.canvas)
|
||
synchronizer.enabled = true
|
||
},
|
||
disabledAnnotationSync(synchronizer) {
|
||
this.AnnotationSync = null
|
||
synchronizer.enabled = false
|
||
synchronizer.remove(this.$refs.canvas)
|
||
this.setAllToolsPassive()
|
||
},
|
||
onContextmenu(e) {
|
||
e.stopImmediatePropagation()
|
||
e.stopPropagation()
|
||
e.preventDefault()
|
||
// const colormapsList = cornerstone.colors.getColormapsList()
|
||
// const colorItems = []
|
||
// colorItems.push({
|
||
// label: '默认值',
|
||
// onClick: () => {
|
||
// this.setColormap()
|
||
// }
|
||
// })
|
||
// colormapsList.forEach(colormap => {
|
||
// const item = {}
|
||
// item.label = colormap.name
|
||
// item.onClick = () => {
|
||
// this.setColormap(colormap.id)
|
||
// }
|
||
// colorItems.push(item)
|
||
// })
|
||
// this.$contextmenu({
|
||
// items: [
|
||
// {
|
||
// label: '移动',
|
||
// divided: true,
|
||
// onClick: () => {
|
||
// this.setToolActive('Pan')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '缩放',
|
||
// divided: true,
|
||
// children: [
|
||
// {
|
||
// label: '自由缩放',
|
||
// onClick: () => {
|
||
// this.setToolActive('Zoom')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '适应图像',
|
||
// onClick: () => {
|
||
// this.fitToWindow()
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '适应窗口',
|
||
// onClick: () => {
|
||
// this.fitToImage()
|
||
// }
|
||
// }
|
||
// ]
|
||
// },
|
||
// {
|
||
// label: '透镜',
|
||
// divided: true,
|
||
// onClick: () => {
|
||
// this.setToolActive('Magnify')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '旋转',
|
||
// divided: true,
|
||
// children: [
|
||
// {
|
||
// label: '默认值',
|
||
// onClick: () => {
|
||
// this.resetRotate()
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '自由旋转',
|
||
// onClick: () => {
|
||
// this.setToolActive('Rotate')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '水平翻转',
|
||
// onClick: () => {
|
||
// this.setRotate(true, false, 0)
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '垂直翻转',
|
||
// onClick: () => {
|
||
// this.setRotate(false, true, 0)
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '左转90度',
|
||
// onClick: () => {
|
||
// this.setRotate(false, false, -90)
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '右转90度',
|
||
// onClick: () => {
|
||
// this.setRotate(false, false, 90)
|
||
// }
|
||
// }
|
||
// ]
|
||
// },
|
||
|
||
// {
|
||
// label: '测量',
|
||
// divided: true,
|
||
// minWidth: 0,
|
||
// children: [
|
||
// {
|
||
// label: '探针',
|
||
// onClick: () => {
|
||
// this.setToolActive('Probe')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '长度测量',
|
||
// onClick: () => {
|
||
// this.setToolActive('Length')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '角度测量',
|
||
// onClick: () => {
|
||
// this.setToolActive('Angle')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: 'Cobb测量',
|
||
// onClick: () => {
|
||
// this.setToolActive('CobbAngle')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '椭圆测量',
|
||
// onClick: () => {
|
||
// this.setToolActive('EllipticalRoi')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '矩形测量',
|
||
// onClick: () => {
|
||
// this.setToolActive('RectangleRoi')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '多边形标记',
|
||
// onClick: () => {
|
||
// this.setToolActive('FreehandRoi')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '十字线',
|
||
// onClick: () => {
|
||
// this.setToolActive('Bidirectional')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '文字标注',
|
||
// onClick: () => {
|
||
// this.setToolActive('ArrowAnnotate')
|
||
// }
|
||
// }
|
||
// ]
|
||
// },
|
||
// {
|
||
// label: '调窗',
|
||
// divided: true,
|
||
// onClick: () => {
|
||
// this.setToolActive('Wwwc')
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '反色',
|
||
// divided: true,
|
||
// onClick: () => {
|
||
// this.toggleInvert()
|
||
// }
|
||
// },
|
||
// {
|
||
// label: '伪彩',
|
||
// children: colorItems
|
||
// }
|
||
// ],
|
||
// event,
|
||
// // x: event.clientX,
|
||
// // y: event.clientY,
|
||
// customClass: 'class-a',
|
||
// zIndex: 3,
|
||
// minWidth: 100
|
||
// })
|
||
// return false
|
||
},
|
||
getToolSate() {
|
||
const toolROITypes = [
|
||
'Probe',
|
||
'EllipticalRoi',
|
||
'RectangleRoi',
|
||
'ArrowAnnotate',
|
||
'Length',
|
||
'CobbAngle',
|
||
'Angle',
|
||
'Bidirectional',
|
||
'FreehandRoi',
|
||
]
|
||
for (let i = 0; i < toolROITypes.length; i++) {
|
||
const toolROIType = toolROITypes[i]
|
||
const toolROIData = JSON.stringify(
|
||
cornerstoneTools.getToolState(this.canvas, toolROIType)
|
||
)
|
||
|
||
if (toolROIData !== undefined) {
|
||
this.allROIToolData[toolROITypes[i]] = JSON.parse(toolROIData)
|
||
}
|
||
}
|
||
},
|
||
clearToolState() {
|
||
ToolStateManager.clear(this.canvas)
|
||
cornerstone.updateImage(this.canvas)
|
||
},
|
||
removeLabel(item) {
|
||
const promise = scroll(this.canvas, item.data.imageIdIndex)
|
||
const scope = this
|
||
Promise.all([promise]).then((res) => {
|
||
cornerstoneTools.removeToolState(scope.canvas, item.type, item.data)
|
||
cornerstone.updateImage(scope.canvas)
|
||
})
|
||
},
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.info-series {
|
||
position: absolute;
|
||
left: 10px;
|
||
top: 10px;
|
||
text-align: left;
|
||
color: #ddd;
|
||
font-size: 12px;
|
||
/* z-index: 1; */
|
||
}
|
||
|
||
.info-image {
|
||
position: absolute;
|
||
left: 10px;
|
||
bottom: 10px;
|
||
text-align: left;
|
||
color: #ddd;
|
||
font-size: 12px;
|
||
/* z-index: 1; */
|
||
}
|
||
|
||
.info-subject {
|
||
position: absolute;
|
||
right: 15px;
|
||
top: 10px;
|
||
text-align: right;
|
||
color: #ddd;
|
||
font-size: 12px;
|
||
/* z-index: 1; */
|
||
}
|
||
|
||
.info-instance {
|
||
position: absolute;
|
||
right: 15px;
|
||
bottom: 10px;
|
||
text-align: right;
|
||
color: #ddd;
|
||
font-size: 12px;
|
||
/* z-index: 1; */
|
||
}
|
||
|
||
.load-indicator {
|
||
position: absolute;
|
||
left: 10px;
|
||
top: 10px;
|
||
text-align: left;
|
||
/* z-index: 1; */
|
||
}
|
||
|
||
.magnifyTool {
|
||
border: 2px solid #ffffff;
|
||
border-radius: 50%;
|
||
display: none;
|
||
cursor: none;
|
||
}
|
||
|
||
.menu__item {
|
||
display: block;
|
||
line-height: 20px;
|
||
text-align: center;
|
||
margin: 10px;
|
||
cursor: default;
|
||
}
|
||
|
||
.menu__item:hover {
|
||
color: #ff0000;
|
||
}
|
||
|
||
.menu {
|
||
height: auto;
|
||
width: auto;
|
||
position: absolute;
|
||
font-size: 14px;
|
||
text-align: left;
|
||
border-radius: 10px;
|
||
border: 1px solid #c21111;
|
||
background-color: #ffffff;
|
||
}
|
||
|
||
li:hover {
|
||
background-color: #e0e0e2;
|
||
color: white;
|
||
}
|
||
|
||
.my_slider_box:after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: -20px;
|
||
left: 0;
|
||
height: 20px;
|
||
width: 100%;
|
||
background: #333;
|
||
}
|
||
</style>
|