基于cornerstone3D的dicom影像浏览器 第五章 在Displayer四个角落显示信息
先看效果
dicom四个角落显示信息
1.在displayer.vue文件中引入对应的依赖
import { vec3 } from "gl-matrix";
import {RenderingEngine,getRenderingEngine,Enums,utilities as csUtils,
} from "@cornerstonejs/core";
const { IMAGE_RENDERED, CAMERA_MODIFIED } = Enums.Events;
import { utilities } from "@cornerstonejs/tools";
const { getOrientationStringLPS, invertOrientationStringLPS } =utilities.orientation;
2.监听事件
mounted() {...this.$refs.displayer.addEventListener(IMAGE_RENDERED, this.onImageRendered);this.$refs.displayer.addEventListener(CAMERA_MODIFIED,this.onCameraModified);...},
3.相关函数
methods:{onImageRendered() {if (!this.state.series) return;this.drawText();},onCameraModified(event) {if (!this.state.series) return;const markers = this.getOrientationMarkers({image: this.state.image,camera: event.detail.camera,rotation: event.detail.rotation,});this.orientation.top = markers.top;this.orientation.bottom = markers.bottom;this.orientation.left = markers.left;this.orientation.right = markers.right;},drawText() {const canvas = this.$refs.displayer.querySelector(".cornerstone-canvas");const context = canvas.getContext("2d");const cvs_w = canvas.clientWidth;const cvs_h = canvas.clientHeight;const mtx = context.getTransform();context.resetTransform();context.font = "14px Arial";context.fillStyle = "white";context.textAlign = "left";context.textBaseline = "top";const idx = this.state.viewport.getCurrentImageIdIndex();const imageId = this.state.imageIds[idx];const image = this.state.series.GetImageById(imageId);let x = 5;let y = 5;let h = 17;let val;// 左上角 left-top// 姓名val = image.PatientName;context.fillText(val, x, y);y += h;// PatientIdval = image.PatientID;context.fillText(val, x, y);y += h;// 年龄(或者生日)+性别val = image.AgeAndSex;if (val) {context.fillText(val, x, y);y += h;}// Image Commentsval = image.ImageComments;if (val) {context.fillText(val, x, y);y += h;}// 左下角 left-bottomy = cvs_h - h;// 医院名val = image.HospitalName;if (val) {context.fillText(val, x, y);y -= h;}// 图像时间val = image.ContentDate + " " + image.ContentTime;if (val) {context.fillText(val, x, y);y -= h;}// Study Descriptionval = image.StudyDesc;if (val) {context.fillText(val, x, y);y -= h;}//series Descriptionval = image.SeriesDesc;if (val) {context.fillText(val, x, y);y -= h;}//患者方向val = image.PatientPosition;if (val) {context.fillText(val, x, y);y -= h;}// 右上角 right-topconst rmargin = 5;y = 5;const range = this.state.viewport.getProperties().voiRange || {lower: -1024,upper: 1024,};const wwwl = csUtils.windowLevel.toWindowLevel(range.lower, range.upper);val = "WL:" + wwwl.windowCenter.toFixed(0);val += " WW:" + wwwl.windowWidth.toFixed(0);x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y += h;// Image No-Countval = "Im:" + (idx + 1) + "/" + this.state.series.GetCount();x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y += h;// Series Noval = image.SeriesNo;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y += h;}// modalityval = image.DeviceName;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);}// 右下角 right-bottomy = cvs_h - h;// Thickness-Locationval = image.ThicknessLocation;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y -= h;}// 曝光参数val = image.Exposure;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y -= h;}// 拍片参数val = image.TrTe;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y -= h;}// Zoomconst imageData = this.state.viewport.getImageData();const camera = this.state.viewport.getCamera();let spacing = [1, 1, 1];if (imageData) {spacing = imageData.spacing;}const t = cvs_h * spacing[1] * 0.5;const scale = t / camera.parallelScale;val = "Zoom:" + scale.toFixed(2);x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);context.setTransform(mtx);},getOrientationMarkers({ camera, rotation }) {// const { rotation, previousCamera, camera } = detail;let flipVertical = camera.flipVertical || false;let flipHorizontal = camera.flipHorizontal || false;let newRotation = rotation || 0;let rowCosines, columnCosines;const { viewUp, viewPlaneNormal } = camera;const viewRight = vec3.create();vec3.cross(viewRight, viewUp, viewPlaneNormal);columnCosines = [-viewUp[0], -viewUp[1], -viewUp[2]];rowCosines = viewRight;const rowString = getOrientationStringLPS(rowCosines);const columnString = getOrientationStringLPS(columnCosines);const oppositeRowString = invertOrientationStringLPS(rowString);const oppositeColumnString = invertOrientationStringLPS(columnString);const markers = {top: oppositeColumnString,left: oppositeRowString,right: rowString,bottom: columnString,};// If any vertical or horizontal flips are applied, change the orientation strings ahead of// the rotation applicationsif (flipVertical) {markers.top = invertOrientationStringLPS(markers.top);markers.bottom = invertOrientationStringLPS(markers.bottom);}if (flipHorizontal) {markers.left = invertOrientationStringLPS(markers.left);markers.right = invertOrientationStringLPS(markers.right);}// Swap the labels accordingly if the viewport has been rotated// This could be done in a more complex way for intermediate rotation values (e.g. 45 degrees)if (newRotation === 90 || newRotation === -270) {return {top: markers.left,left: invertOrientationStringLPS(markers.top),right: invertOrientationStringLPS(markers.bottom),bottom: markers.right, // left};} else if (newRotation === -90 || newRotation === 270) {return {top: invertOrientationStringLPS(markers.left),left: markers.top,bottom: markers.left,right: markers.bottom,};} else if (newRotation === 180 || newRotation === -180) {return {top: invertOrientationStringLPS(markers.top),left: invertOrientationStringLPS(markers.left),bottom: invertOrientationStringLPS(markers.bottom),right: invertOrientationStringLPS(markers.right),};}return markers;},
}