898 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			898 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
| <template>
 | |
|   <div
 | |
|     id="canvas"
 | |
|     ref="canvas"
 | |
|     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"
 | |
|   >
 | |
|     <div v-show="dicomInfo.series" class="info-series">
 | |
|       <div>Series #{{ dicomInfo.series }}</div>
 | |
|       <div>Image #{{ dicomInfo.frame }}</div>
 | |
|       <div>{{ dicomInfo.modality }}</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>
 | |
| 
 | |
|     <div class="info-subject">
 | |
|       <!-- <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 v-show="stack.firstImageLoading" class="load-indicator">
 | |
|       Loading Series #{{ stack.seriesNumber }}...
 | |
|     </div>-->
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import Vue from 'vue'
 | |
| import Contextmenu from 'vue-contextmenujs'
 | |
| Vue.use(Contextmenu)
 | |
| import * as cornerstone from 'cornerstone-core'
 | |
| import * as cornerstoneMath from 'cornerstone-math'
 | |
| import * as cornerstoneTools from 'cornerstone-tools'
 | |
| const scroll = cornerstoneTools.import('util/scrollToIndex')
 | |
| import Hammer from 'hammerjs'
 | |
| 
 | |
| cornerstoneTools.external.cornerstone = cornerstone
 | |
| cornerstoneTools.external.Hammer = Hammer
 | |
| cornerstoneTools.external.cornerstoneMath = cornerstoneMath
 | |
| cornerstoneTools.toolStyle.setToolWidth(2)
 | |
| cornerstoneTools.toolColors.setToolColor('rgb(255, 255, 0)')
 | |
| cornerstoneTools.toolColors.setActiveColor('rgb(0, 255, 0)')
 | |
| // cornerstoneTools.init({ showSVGCursors: true })
 | |
| cornerstoneTools.init()
 | |
| const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
 | |
| export default {
 | |
|   data() {
 | |
|     return {
 | |
|       loading: false,
 | |
|       canvas: {},
 | |
|       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,
 | |
|         fps: 5
 | |
|       },
 | |
|       toolState: {
 | |
|         initialized: false,
 | |
|         activeTool: 'none',
 | |
|         dicomInfoVisible: false,
 | |
|         clipPlaying: false,
 | |
|         viewportInvert: false
 | |
|       },
 | |
|       loadImagePromise: null,
 | |
|       AnnotationSync: null,
 | |
|       allROIToolData: {},
 | |
|       type: '',
 | |
|       series: '',
 | |
|       ToolStateManager
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   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
 | |
|     )
 | |
|   },
 | |
| 
 | |
|   methods: {
 | |
|     loadImageStack(dicomSeries) {
 | |
|       this.series = dicomSeries
 | |
|       this.stack.seriesId = dicomSeries.seriesId
 | |
|       this.stack.seriesNumber = dicomSeries.seriesNumber
 | |
|       this.stack.imageIds = dicomSeries.imageIds
 | |
|       this.stack.currentImageIdIndex = 0
 | |
|       this.stack.firstImageLoading = true
 | |
|       if (this.toolState.clipPlaying) this.toggleClipPlay()
 | |
|       this.toolState.viewportInvert = false
 | |
|       this.toolState.dicomInfoVisible = false
 | |
|       const imageId = this.stack.imageIds[this.stack.currentImageIdIndex]
 | |
|       this.stack.instanceId = imageId.split('/')[imageId.split('/').length - 1]
 | |
|       const element = this.$refs.canvas
 | |
|       cornerstone.enable(element)
 | |
| 
 | |
|       var scope = this
 | |
|       // cornerstone.imageCache.setMaximumSizeBytes(100000)
 | |
|       this.loading = true
 | |
|       // cornerstone.loadImage(this.stack.imageIds[this.stack.currentImageIdIndex])
 | |
|       cornerstone.loadAndCacheImage(this.stack.imageIds[this.stack.currentImageIdIndex])
 | |
|         .then(image => {
 | |
|           this.loading = false
 | |
|           scope.onFirstImageLoaded(image)
 | |
|         }).catch((error) => {
 | |
|           this.loading = false
 | |
|           if (error.error && error.error.message) {
 | |
|             this.$message.error(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) {
 | |
|               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,
 | |
|             cornerstoneTools.StackScrollMouseWheelTool
 | |
|           )
 | |
|         ) {
 | |
|           cornerstoneTools.addToolForElement(
 | |
|             element,
 | |
|             cornerstoneTools.StackScrollMouseWheelTool
 | |
|           )
 | |
|         }
 | |
|         cornerstoneTools.setToolActiveForElement(
 | |
|           element,
 | |
|           'StackScrollMouseWheel',
 | |
|           {}
 | |
|         )
 | |
|         if (
 | |
|           !cornerstoneTools.getToolForElement(
 | |
|             element,
 | |
|             cornerstoneTools.ScaleOverlayTool
 | |
|           )
 | |
|         ) {
 | |
|           cornerstoneTools.addToolForElement(
 | |
|             element,
 | |
|             cornerstoneTools.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', 'stackPrefetch', 'playClip'])
 | |
|       cornerstoneTools.addToolState(this.canvas, 'stack', this.stack)
 | |
|       cornerstoneTools.stackPrefetch.enable(this.canvas)
 | |
|       // 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]
 | |
|     },
 | |
|     onNewImage(e) {
 | |
|       e.detail.enabledElement.options = {}
 | |
|       var data = e.detail.image.data
 | |
|       this.dicomInfo.hospital = data.string('x00080080')
 | |
|       // 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')
 | |
|       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('x00280010')}x${data.uint16(
 | |
|         'x00280011'
 | |
|       )}`
 | |
|       // var pixel = data.floatString('x00280030')
 | |
|       if (this.dicomInfo.pixel) {
 | |
|         this.dicomInfo.pixel = this.dicomInfo.pixel.toFixed(2)
 | |
|       }
 | |
|       this.dicomInfo.thick = data.floatString('x00180050') // 切片厚度
 | |
|       if (this.dicomInfo.thick) {
 | |
|         this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2)
 | |
|       }
 | |
|     },
 | |
|     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 viewport = e.detail.viewport
 | |
|       this.dicomInfo.wwwc = `${Math.round(
 | |
|         viewport.voi.windowWidth
 | |
|       )}/${Math.round(viewport.voi.windowCenter)}` // 窗位
 | |
|       this.dicomInfo.zoom = viewport.scale.toFixed(2)
 | |
|       var data = e.detail.image.data
 | |
|       const position = data.string('x00200032')
 | |
|       this.dicomInfo.location = position ? Number(
 | |
|         position.split('\\')[position.split('\\').length - 1]
 | |
|       ).toFixed(2) : ''
 | |
|     },
 | |
|     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
 | |
|     },
 | |
|     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) {
 | |
|       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.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 = false
 | |
|     },
 | |
|     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)
 | |
|       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() {
 | |
|       var viewport = cornerstone.getViewport(this.canvas)
 | |
|       viewport.hflip = false
 | |
|       viewport.vflip = false
 | |
|       viewport.rotation = 0
 | |
|       cornerstone.setViewport(this.canvas, viewport)
 | |
|     },
 | |
| 
 | |
|     setRotate(hflip, vflip, angle) {
 | |
|       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`)
 | |
|     },
 | |
|     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)
 | |
|     },
 | |
|     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(event) {
 | |
|       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;
 | |
|   /* z-index: 1; */
 | |
| }
 | |
| .info-image {
 | |
|   position: absolute;
 | |
|   left: 10px;
 | |
|   bottom: 10px;
 | |
|   text-align: left;
 | |
|   /* z-index: 1; */
 | |
| }
 | |
| 
 | |
| .info-subject {
 | |
|   position: absolute;
 | |
|   right: 10px;
 | |
|   top: 10px;
 | |
|   text-align: right;
 | |
|   /* 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;
 | |
| }
 | |
| </style>
 |