基于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;
      // PatientId
      val = image.PatientID;
      context.fillText(val, x, y);
      y += h;
      // 年龄(或者生日)+性别
      val = image.AgeAndSex;
      if (val) {
        context.fillText(val, x, y);
        y += h;
      }
      // Image Comments
      val = image.ImageComments;
      if (val) {
        context.fillText(val, x, y);
        y += h;
      }

      // 左下角 left-bottom
      y = 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 Description
      val = image.StudyDesc;
      if (val) {
        context.fillText(val, x, y);
        y -= h;
      }
      //series Description
      val = image.SeriesDesc;
      if (val) {
        context.fillText(val, x, y);
        y -= h;
      }
      //患者方向
      val = image.PatientPosition;
      if (val) {
        context.fillText(val, x, y);
        y -= h;
      }

      // 右上角 right-top
      const 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-Count
      val = "Im:" + (idx + 1) + "/" + this.state.series.GetCount();
      x = cvs_w - rmargin - context.measureText(val).width;
      context.fillText(val, x, y);
      y += h;
      // Series No
      val = image.SeriesNo;
      if (val) {
        x = cvs_w - rmargin - context.measureText(val).width;
        context.fillText(val, x, y);
        y += h;
      }
      // modality
      val = image.DeviceName;
      if (val) {
        x = cvs_w - rmargin - context.measureText(val).width;
        context.fillText(val, x, y);
      }

      // 右下角 right-bottom
      y = cvs_h - h;
      // Thickness-Location
      val = 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;
      }
      // Zoom
      const 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 applications
      if (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;
    },
}
相关推荐
ghie90905 分钟前
MATLAB中编写不平衡磁拉力方程
开发语言·matlab
weixin_4521595514 分钟前
C++与Java性能对比
开发语言·c++·算法
会叫的恐龙18 分钟前
C++ 核心知识点汇总(第一日)(输入输出与变量、类型转换)
开发语言·c++
2301_7657031421 分钟前
C++中的工厂模式实战
开发语言·c++·算法
晚霞的不甘22 分钟前
Flutter for OpenHarmony构建全功能视差侧滑菜单系统:从动效设计到多页面导航的完整实践
前端·学习·flutter·microsoft·前端框架·交互
黎子越22 分钟前
python相关练习
java·前端·python
电商API&Tina26 分钟前
电商数据采集 API 接口 全维度解析(技术 + 商业 + 合规)
java·大数据·开发语言·数据库·人工智能·json
小白学大数据30 分钟前
实测数据:多进程、多线程、异步协程爬虫速度对比
开发语言·爬虫·python·php
摘星编程34 分钟前
用React Native开发OpenHarmony应用:StickyHeader粘性标题
javascript·react native·react.js
A_nanda38 分钟前
c# 用VUE+elmentPlus生成简单管理系统
javascript·vue.js·c#