我们需要把用到的文件下载到public目录,之后在vue的index.html里引用
我们还需要在页面里做引入
window.cornerstoneTools.external.cornerstone = window.cornerstone;
window.cornerstoneWADOImageLoader.external.cornerstone = window.cornerstone;
window.cornerstoneWADOImageLoader.external.dicomParser = window.dicomParser;
window.cornerstoneTools.external.cornerstoneMath = window.cornerstoneMath;
window.cornerstoneTools.external.Hammer = window.Hammer;
ts需要给上面的引入api定义类型,不然报错
接下来进行图片的展示并初始化功能
const element = document.getElementById('medical-imaging');
let imageId: string = '';
window.cornerstone.enable(element);
imageId = `wadouri:${data.reportUrlList[num]}`;
window.cornerstone.loadImage(imageId).then((image: any) => {
window.cornerstone.displayImage(element, image);
// 激活开关
window.cornerstoneTools.mouseInput.enable(element); // 鼠标按下事件
window.cornerstoneTools.mouseWheelInput.enable(element); // 鼠标滚轮事件
window.cornerstoneTools.wwwc.activate(element, 1); // 允许改变窗宽窗位
window.cornerstoneTools.pan.activate(element, 2); // 允许平移
window.cornerstoneTools.zoom.activate(element, 4); // 允许缩放
window.cornerstoneTools.touchInput.enable(element); // 手势事件
window.cornerstoneTools.zoomTouchPinch.activate(element);
window.cornerstoneTools.length.activate(element); // 长度
window.cornerstoneTools.probe.activate(element, 1); // 探索
window.cornerstoneTools.ellipticalRoi.activate(element, 1); // 椭圆
window.cornerstoneTools.rectangleRoi.activate(element, 1); // 矩形
window.cornerstoneTools.angle.activate(element, 1); // 角度
window.cornerstoneTools.highlight.activate(element, 1); // 高亮
window.cornerstoneTools.freehand.activate(element, 1); // 画笔
window.cornerstoneTools.stackScroll.activate(element); // 堆积滚动
window.cornerstoneTools.arrowAnnotate.activate(element, 1); // 箭头注解
window.cornerstoneTools.wwwcTouchDrag.disable(element); // 关闭灰度值
window.cornerstoneTools.wwwc.deactivate(element, 1); // 不允许改变窗宽窗位
// 默认开启
window.cornerstoneTools.zoomWheel.activate(element); // 缩放
const canvasStack = {
currentImageIdIndex: 0,
imageIds: image,
};
window.cornerstoneTools.addStackStateManager(element, ['stack']);
window.cornerstoneTools.addToolState(element, 'stack', canvasStack); // 将工具状态添加到toolStateManager,这由工具以及恢复已保存状态的模块完成。addToolState(element, toolType, measurementData)
window.cornerstoneTools.stackScrollWheel.activate(element); // Mouse wheel
// cornerstoneTools.scrollIndicator.enable(element); // Position indicator
});
之后可以封装一个功能调用的方法
const cornerstoneSwitch = (name?: string) => {
const element = document.getElementById('medical-imaging');
if (name && ['probe', 'rectangleRoi', 'angle', 'arrowAnnotate', 'length', 'ellipticalRoi'].includes(name)) {
data.nameList.push(name);
}
if (name === 'newLoad') {
window.cornerstone.reset(element);
}
if (name === 'clear') {
if (data.nameList.length > 0) {
data.nameList.forEach((i) => {
window.cornerstoneTools.clearToolState(element, i);
});
data.nameList.length = 0;
}
}
if (name === 'revocation') {
if (data.nameList.length > 0) {
window.cornerstoneTools.clearToolState(element, data.nameList[data.nameList.length - 1]);
data.nameList.length -= 1;
}
}
// 默认关闭
window.cornerstoneTools.panTouchDrag.deactivate(element); // 拖拽-移动
window.cornerstoneTools.probeTouch.deactivate(element); // 探索并标注所处坐标数据
window.cornerstoneTools.zoomTouchDrag.deactivate(element); // 拖拽并放大
window.cornerstoneTools.lengthTouch.deactivate(element); // 长度记录
window.cornerstoneTools.ellipticalRoiTouch.deactivate(element); // 画圆/椭圆
window.cornerstoneTools.rectangleRoiTouch.deactivate(element); // 画矩形
window.cornerstoneTools.angleTouch.deactivate(element); // 画角
window.cornerstoneTools.arrowAnnotateTouch.deactivate(element); // 箭头
window.cornerstoneTools.rotateTouchDrag.deactivate(element); // 自由旋转
window.cornerstoneTools.wwwcTouchDrag.deactivate(element); // Drag灰度值与数据值调整
window.cornerstone.setViewport(element, {
invert: false, // 正负片-负像
vflip: false, // 垂直翻转
hflip: false, // 水平翻转
});
// 是否开启
window.cornerstoneTools.zoomWheel.activate(element); // 缩放
if (name === 'panTouchDrag') {
window.cornerstoneTools.panTouchDrag.activate(element); // 拖拽-移动
}
if (name === 'probe') {
window.cornerstoneTools.probeTouch.activate(element); // 探索并标注所处坐标数据
}
if (name === 'zoomTouchDrag') {
window.cornerstoneTools.zoomWheel.deactivate(element); // 关闭缩放
window.cornerstoneTools.zoomTouchDrag.activate(element); // 拖拽并放大
}
if (name === 'length') {
window.cornerstoneTools.lengthTouch.activate(element); // 长度记录
}
if (name === 'ellipticalRoi') {
window.cornerstoneTools.ellipticalRoiTouch.activate(element); // 画圆/椭圆
}
if (name === 'rectangleRoi') {
window.cornerstoneTools.rectangleRoiTouch.activate(element); // 画矩形
}
if (name === 'angle') {
window.cornerstoneTools.angleTouch.activate(element); // 画角
}
if (name === 'arrowAnnotate') {
window.cornerstoneTools.arrowAnnotateTouch.activate(element); // 箭头
}
if (name === 'rotateTouchDrag') {
window.cornerstoneTools.rotateTouchDrag.activate(element); // 自由旋转
}
if (name === 'wwwcTouchDrag') {
window.cornerstoneTools.wwwcTouchDrag.activate(element); // Drag灰度值与数据值调整
}
window.cornerstone.setViewport(element, {
invert: name === 'invert', // 正负片-负像
vflip: name === 'vflip', // 垂直翻转
hflip: name === 'hflip', // 水平翻转
});
};
下面是我页面的完整代码
<!-- 支持app 查看dicom医学影像 -->
<template>
<div class="flex-page">
<template v-if="dataLoadingOver">
<template v-if="reportUrlList.length > 0">
<div class="meun-list">
<div
v-for="(item, index) of items"
:key="item.id"
:class="['meun-title', { 'active-menu-title': index === checkedIndex }]"
@click.stop="checkedMenu(index)"
>
{{ item.name }}
</div>
<div class="shrink-btn" @click="isShrink = !isShrink"><van-icon :name="isShrink ? 'arrow-down' : 'arrow-up'" /></div>
<div v-show="!isShrink" class="meun-content">
<div
v-for="(item, index) of items[checkedIndex].content"
:key="index"
class="button-part"
:class="{ checked: index === checkedChildIndex }"
@click.stop="checkFunction(index, item.nameEN)"
>
<div><img :src="getImageSrc(`cloud-imagine-film/icon_${item.img}.png`)" alt="" /></div>
<div>{{ item.nameCN }}</div>
</div>
</div>
</div>
<div id="medical-imaging"></div>
<div class="foot-part">
<button @click="previousPage()">上一张</button>
<button style="color: #fff; background: linear-gradient(332deg, #8796ff 0%, #93b1ff 100%); border: none" @click="nextPage()">下一张</button>
</div>
</template>
<empty-page v-else style="height: 40rem" text="暂无数据" />
</template>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs } from 'vue';
import { commonUtils } from '@utils';
import { Icon } from 'vant';
import EmptyPage from '@components/empty-page.vue';
import procedureService from '@api/procedure.service';
window.cornerstoneTools.external.cornerstone = window.cornerstone;
window.cornerstoneWADOImageLoader.external.cornerstone = window.cornerstone;
window.cornerstoneWADOImageLoader.external.dicomParser = window.dicomParser;
window.cornerstoneTools.external.cornerstoneMath = window.cornerstoneMath;
window.cornerstoneTools.external.Hammer = window.Hammer;
export default defineComponent({
components: {
'empty-page': EmptyPage,
'van-icon': Icon,
},
props: {
procedureId: {
type: String,
required: true,
default: '',
},
},
setup: (props) => {
let num: number = 0;
const data = reactive({
dataLoadingOver: false,
checkedIndex: 0,
checkedChildIndex: -1,
isShrink: true,
pageNo: 1,
pageSize: 5,
lastPage: false,
items: [
{
id: 0,
name: '图像',
content: [
{ nameCN: '移动', img: 'pan', nameEN: 'panTouchDrag' },
{ nameCN: '定点缩放', img: 'zoom', nameEN: 'zoomTouchDrag' },
{ nameCN: '灰度值', img: 'wwwc', nameEN: 'wwwcTouchDrag' },
{ nameCN: '自由旋转', img: 'rotate', nameEN: 'rotateTouchDrag' },
{ nameCN: '负像', img: 'invert', nameEN: 'invert' },
{ nameCN: '垂直翻转', img: 'vflip', nameEN: 'vflip' },
{ nameCN: '水平翻转', img: 'hflip', nameEN: 'hflip' },
{ nameCN: '重置', img: 'load', nameEN: 'newLoad' },
],
},
{
id: 1,
name: '标注',
content: [
{ nameCN: '标记', img: 'probe', nameEN: 'probe' },
{ nameCN: '矩形', img: 'rectangle', nameEN: 'rectangleRoi' },
{ nameCN: '角度', img: 'angle', nameEN: 'angle' },
{ nameCN: '箭头', img: 'arrow', nameEN: 'arrowAnnotate' },
{ nameCN: '长度', img: 'length', nameEN: 'length' },
{ nameCN: '圆/椭圆', img: 'elliptical', nameEN: 'ellipticalRoi' },
{ nameCN: '撤销', img: 'revocation', nameEN: 'revocation' },
{ nameCN: '清空元素', img: 'clear', nameEN: 'clear' },
],
},
],
nameList: [] as string[],
reportUrlList: [] as string[],
});
const getDicomInfo = async () => {
commonUtils.showLoading();
await procedureService
.getCloudImagingMediaUrlList(props.procedureId, data.pageNo, data.pageSize)
.then((res) => {
if (!res.entityList || res.entityList.length === 0) {
data.lastPage = true;
return;
}
data.reportUrlList.push(...res.entityList);
data.pageNo++;
})
.catch((err) => {
commonUtils.alert(err?.responseText || '获取页面信息失败');
})
.finally(() => {
commonUtils.hideLoading();
data.dataLoadingOver = true;
});
};
const getDetailInfo = async () => {
const cloudImagingInfo = await procedureService.getCloudImagingInfoByProcedureId(props.procedureId, '', commonUtils.getOrgGroupId());
document.title = cloudImagingInfo?.procedureName || '影像展示';
};
const dicomParser = async () => {
commonUtils.showLoading();
const element = document.getElementById('medical-imaging');
let imageId: string = '';
window.cornerstone.enable(element);
imageId = `wadouri:${data.reportUrlList[num]}`;
window.cornerstone.loadImage(imageId).then((image: any) => {
window.cornerstone.displayImage(element, image);
// 激活开关
window.cornerstoneTools.mouseInput.enable(element); // 鼠标按下事件
window.cornerstoneTools.mouseWheelInput.enable(element); // 鼠标滚轮事件
window.cornerstoneTools.wwwc.activate(element, 1); // 允许改变窗宽窗位
window.cornerstoneTools.pan.activate(element, 2); // 允许平移
window.cornerstoneTools.zoom.activate(element, 4); // 允许缩放
window.cornerstoneTools.touchInput.enable(element); // 手势事件
window.cornerstoneTools.zoomTouchPinch.activate(element);
window.cornerstoneTools.length.activate(element); // 长度
window.cornerstoneTools.probe.activate(element, 1); // 探索
window.cornerstoneTools.ellipticalRoi.activate(element, 1); // 椭圆
window.cornerstoneTools.rectangleRoi.activate(element, 1); // 矩形
window.cornerstoneTools.angle.activate(element, 1); // 角度
window.cornerstoneTools.highlight.activate(element, 1); // 高亮
window.cornerstoneTools.freehand.activate(element, 1); // 画笔
window.cornerstoneTools.stackScroll.activate(element); // 堆积滚动
window.cornerstoneTools.arrowAnnotate.activate(element, 1); // 箭头注解
window.cornerstoneTools.wwwcTouchDrag.disable(element); // 关闭灰度值
window.cornerstoneTools.wwwc.deactivate(element, 1); // 不允许改变窗宽窗位
// 默认开启
window.cornerstoneTools.zoomWheel.activate(element); // 缩放
const canvasStack = {
currentImageIdIndex: 0,
imageIds: image,
};
window.cornerstoneTools.addStackStateManager(element, ['stack']);
window.cornerstoneTools.addToolState(element, 'stack', canvasStack); // 将工具状态添加到toolStateManager,这由工具以及恢复已保存状态的模块完成。addToolState(element, toolType, measurementData)
window.cornerstoneTools.stackScrollWheel.activate(element); // Mouse wheel
// cornerstoneTools.scrollIndicator.enable(element); // Position indicator
});
commonUtils.hideLoading();
};
const cornerstoneSwitch = (name?: string) => {
const element = document.getElementById('medical-imaging');
if (name && ['probe', 'rectangleRoi', 'angle', 'arrowAnnotate', 'length', 'ellipticalRoi'].includes(name)) {
data.nameList.push(name);
}
if (name === 'newLoad') {
window.cornerstone.reset(element);
}
if (name === 'clear') {
if (data.nameList.length > 0) {
data.nameList.forEach((i) => {
window.cornerstoneTools.clearToolState(element, i);
});
data.nameList.length = 0;
}
}
if (name === 'revocation') {
if (data.nameList.length > 0) {
window.cornerstoneTools.clearToolState(element, data.nameList[data.nameList.length - 1]);
data.nameList.length -= 1;
}
}
// 默认关闭
window.cornerstoneTools.panTouchDrag.deactivate(element); // 拖拽-移动
window.cornerstoneTools.probeTouch.deactivate(element); // 探索并标注所处坐标数据
window.cornerstoneTools.zoomTouchDrag.deactivate(element); // 拖拽并放大
window.cornerstoneTools.lengthTouch.deactivate(element); // 长度记录
window.cornerstoneTools.ellipticalRoiTouch.deactivate(element); // 画圆/椭圆
window.cornerstoneTools.rectangleRoiTouch.deactivate(element); // 画矩形
window.cornerstoneTools.angleTouch.deactivate(element); // 画角
window.cornerstoneTools.arrowAnnotateTouch.deactivate(element); // 箭头
window.cornerstoneTools.rotateTouchDrag.deactivate(element); // 自由旋转
window.cornerstoneTools.wwwcTouchDrag.deactivate(element); // Drag灰度值与数据值调整
window.cornerstone.setViewport(element, {
invert: false, // 正负片-负像
vflip: false, // 垂直翻转
hflip: false, // 水平翻转
});
// 是否开启
window.cornerstoneTools.zoomWheel.activate(element); // 缩放
if (name === 'panTouchDrag') {
window.cornerstoneTools.panTouchDrag.activate(element); // 拖拽-移动
}
if (name === 'probe') {
window.cornerstoneTools.probeTouch.activate(element); // 探索并标注所处坐标数据
}
if (name === 'zoomTouchDrag') {
window.cornerstoneTools.zoomWheel.deactivate(element); // 关闭缩放
window.cornerstoneTools.zoomTouchDrag.activate(element); // 拖拽并放大
}
if (name === 'length') {
window.cornerstoneTools.lengthTouch.activate(element); // 长度记录
}
if (name === 'ellipticalRoi') {
window.cornerstoneTools.ellipticalRoiTouch.activate(element); // 画圆/椭圆
}
if (name === 'rectangleRoi') {
window.cornerstoneTools.rectangleRoiTouch.activate(element); // 画矩形
}
if (name === 'angle') {
window.cornerstoneTools.angleTouch.activate(element); // 画角
}
if (name === 'arrowAnnotate') {
window.cornerstoneTools.arrowAnnotateTouch.activate(element); // 箭头
}
if (name === 'rotateTouchDrag') {
window.cornerstoneTools.rotateTouchDrag.activate(element); // 自由旋转
}
if (name === 'wwwcTouchDrag') {
window.cornerstoneTools.wwwcTouchDrag.activate(element); // Drag灰度值与数据值调整
}
window.cornerstone.setViewport(element, {
invert: name === 'invert', // 正负片-负像
vflip: name === 'vflip', // 垂直翻转
hflip: name === 'hflip', // 水平翻转
});
};
const previousPage = async () => {
if (num === 0) {
commonUtils.showTipMessage('第一页');
} else {
num--;
}
await dicomParser();
cornerstoneSwitch('newLoad');
data.isShrink = true;
};
const nextPage = async () => {
if (num === data.reportUrlList.length - 1) {
if (data.lastPage) {
commonUtils.showTipMessage('最后一页');
return;
}
await getDicomInfo();
} else {
num++;
}
await dicomParser();
cornerstoneSwitch('newLoad');
data.isShrink = true;
};
const checkFunction = (index: number, name: string) => {
data.checkedChildIndex = index;
data.isShrink = true;
cornerstoneSwitch(name);
};
const checkedMenu = (index: number) => {
data.checkedIndex = index;
data.isShrink = false;
data.checkedChildIndex = -1;
};
const allData = toRefs(data);
onMounted(async () => {
await getDicomInfo();
await getDetailInfo();
if (data.reportUrlList.length > 0) {
dicomParser();
}
});
return {
...allData,
previousPage,
nextPage,
checkFunction,
checkedMenu,
getImageSrc: commonUtils.getImageSrc,
};
},
});
</script>
<style lang="scss" scoped>
.flex-page {
height: 100vh;
:deep(.van-popup--center) {
line-height: 10rem;
text-align: center;
font-size: 2rem;
}
#medical-imaging {
margin: 2rem;
height: 80vh;
background-color: rgb(8, 8, 8);
}
.foot-part {
padding: 1rem 2rem;
width: 100%;
position: fixed;
bottom: 0;
height: 5rem;
display: flex;
justify-content: space-around;
align-items: center;
margin-bottom: 2rem;
button {
background: #fff;
font-size: 1.8rem;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold;
color: #7891ec;
line-height: 1.8rem;
width: 15.2rem;
text-align: center;
height: 4.4rem;
line-height: 4.4rem;
border-radius: 2.8rem;
opacity: 1;
border: 0.1rem solid #819cfc;
}
}
}
.meun-list {
width: 100%;
display: flex;
flex-wrap: wrap;
font-size: 1.4rem;
padding: 1rem 2rem;
color: #666666;
position: relative;
background: black;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: 400;
}
.meun-title {
margin-left: 1rem;
line-height: 1.9rem;
border: 1px solid transparent;
padding: 0 0.4rem;
&:first-child {
margin-left: 0;
}
}
.active-menu-title {
border: 1px solid #819cfc;
border-radius: 0.3rem;
color: #7891ec;
}
.meun-content {
width: 100%;
height: auto;
overflow: auto;
display: flex;
flex-wrap: wrap;
background: black;
position: absolute;
top: 4rem;
left: 0;
}
.button-part {
width: 25%;
padding: 1rem 0;
font-size: 1.3rem;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: 400;
div {
margin: 0 auto;
text-align: center;
img {
width: 3rem;
height: 3rem;
}
}
}
.checked {
background: #999;
color: black;
}
.shrink-btn {
position: absolute;
top: 1rem;
right: 1rem;
}
</style>
最后是页面展示情况
今天公司又让做了一版PC端的
<template>
<div class="container">
<template v-if="mediaUrl || visitId">
<div class="meun-list">
<div
v-for="(item, index) of items"
:key="item.id"
:class="['meun-title', { 'active-menu-title': index === checkedIndex }]"
@click.stop="checkedMenu(index)"
>
{{ item.name }}
</div>
<div class="shrink-btn" @click.stop="isShrink = !isShrink">
<el-icon v-if="isShrink"><icon-arrow-down /></el-icon>
<el-icon v-else><icon-arrow-up /></el-icon>
</div>
<div v-show="!isShrink" class="meun-content">
<div
v-for="(item, index) of items[checkedIndex].content"
:key="index"
class="button-part"
:class="{ checked: index === checkedChildIndex }"
@click.stop="checkFunction(index, item.nameEN)"
>
<div><img :src="getImageSrc(`consultation-management/icon_${item.img}.png`)" alt="" /></div>
<div>{{ item.nameCN }}</div>
</div>
</div>
</div>
<div id="medical-imaging" @click.stop="isShrink = true"></div>
<div class="foot">
<button @click="previousPage">上一页</button>
<button style="color: #fff; background: #3aa0ff; border: none" @click="nextPage">下一页</button>
</div></template
>
<base-default-page v-else error-text="暂无数据" :height="'80vh'"></base-default-page>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, onMounted } from 'vue';
import { ArrowDown as IconArrowDown, ArrowUp as IconArrowUp } from '@element-plus/icons-vue';
import { commonUtils } from '@utils';
import { BaseDefaultPage } from '@components';
import { visitMedia } from '../api';
window.cornerstoneTools.external.cornerstone = window.cornerstone;
window.cornerstoneWADOImageLoader.external.cornerstone = window.cornerstone;
window.cornerstoneWADOImageLoader.external.dicomParser = window.dicomParser;
window.cornerstoneTools.external.cornerstoneMath = window.cornerstoneMath;
window.cornerstoneTools.external.Hammer = window.Hammer;
export default defineComponent({
name: 'VisitDicomPreview',
components: {
BaseDefaultPage,
IconArrowDown,
IconArrowUp,
},
props: {
visitId: {
type: String,
required: false,
default: '',
},
mediaUrl: {
type: String,
required: true,
default: '',
},
},
setup: (props) => {
const visitService = visitMedia.useVisitMediaService();
let imgUrl: any[] = [];
let num: number = 0;
const data = reactive({
checkedIndex: 0,
checkedChildIndex: -1,
isShrink: true,
items: [
{
id: 0,
name: '图像',
content: [
{ nameCN: '移动', img: 'pan', nameEN: 'panTouchDrag' },
{ nameCN: '定点缩放', img: 'zoom', nameEN: 'zoomTouchDrag' },
{ nameCN: '灰度值', img: 'wwwc', nameEN: 'wwwcTouchDrag' },
{ nameCN: '自由旋转', img: 'rotate', nameEN: 'rotateTouchDrag' },
{ nameCN: '负像', img: 'invert', nameEN: 'invert' },
{ nameCN: '垂直翻转', img: 'vflip', nameEN: 'vflip' },
{ nameCN: '水平翻转', img: 'hflip', nameEN: 'hflip' },
{ nameCN: '重置', img: 'load', nameEN: 'newLoad' },
],
},
{
id: 1,
name: '标注',
content: [
{ nameCN: '标记', img: 'probe', nameEN: 'probe' },
{ nameCN: '矩形', img: 'rectangle', nameEN: 'rectangleRoi' },
{ nameCN: '角度', img: 'angle', nameEN: 'angle' },
{ nameCN: '箭头', img: 'arrow', nameEN: 'arrowAnnotate' },
{ nameCN: '长度', img: 'length', nameEN: 'length' },
{ nameCN: '圆/椭圆', img: 'elliptical', nameEN: 'ellipticalRoi' },
{ nameCN: '撤销', img: 'revocation', nameEN: 'revocation' },
{ nameCN: '清空元素', img: 'clear', nameEN: 'clear' },
],
},
],
nameList: [] as string[],
});
const dicomParser = async (name?: string) => {
commonUtils.showLoading();
console.log('x');
if (name && ['probe', 'rectangleRoi', 'angle', 'arrowAnnotate', 'length', 'ellipticalRoi'].includes(name)) {
data.nameList.push(name);
}
const element = document.getElementById('medical-imaging');
if (name === 'newLoad') {
window.cornerstone.reset(element);
}
if (name === 'clear') {
if (data.nameList.length > 0) {
data.nameList.forEach((i) => {
window.cornerstoneTools.clearToolState(element, i);
});
data.nameList.length = 0;
}
}
if (name === 'revocation') {
if (data.nameList.length > 0) {
window.cornerstoneTools.clearToolState(element, data.nameList[data.nameList.length - 1]);
data.nameList.length -= 1;
}
}
let imageId: string = '';
window.cornerstone.enable(element);
if (props.visitId) {
imgUrl = await visitService.getDicomUrlList(props.visitId);
imageId = `wadouri:${imgUrl[num]}`;
} else {
console.log(props.mediaUrl);
const dicomUrl = props.mediaUrl;
console.log('dicomUrl :>> ', dicomUrl);
imageId = `wadouri:${dicomUrl}`;
}
window.cornerstone.loadImage(imageId).then((image: any) => {
window.cornerstone.displayImage(element, image);
// 激活开关
window.cornerstoneTools.mouseInput.enable(element); // 鼠标按下事件
window.cornerstoneTools.mouseWheelInput.enable(element); // 鼠标滚轮事件
window.cornerstoneTools.touchInput.enable(element); // 手势事件
window.cornerstoneTools.zoomTouchPinch.activate(element, 1);
// window.cornerstoneTools.highlight.activate(element, 1); // 高亮
// window.cornerstoneTools.stackScroll.activate(element); // 堆积滚动
// 默认开启
window.cornerstoneTools.zoomWheel.activate(element); // 缩放
});
commonUtils.hideLoading();
};
const cornerstoneSwitch = (name?: string) => {
const element = document.getElementById('medical-imaging');
if (name && ['probe', 'rectangleRoi', 'angle', 'arrowAnnotate', 'length', 'ellipticalRoi'].includes(name)) {
data.nameList.push(name);
}
if (name === 'newLoad') {
window.cornerstone.reset(element);
}
if (name === 'clear') {
if (data.nameList.length > 0) {
data.nameList.forEach((i) => {
window.cornerstoneTools.clearToolState(element, i);
});
data.nameList.length = 0;
}
}
if (name === 'revocation') {
if (data.nameList.length > 0) {
window.cornerstoneTools.clearToolState(element, data.nameList[data.nameList.length - 1]);
data.nameList.length -= 1;
}
}
// 默认关闭
window.cornerstoneTools.wwwc.deactivate(element, 1); // 不允许开启灰度值
window.cornerstoneTools.zoom.deactivate(element, 1); // 不不允许定点缩放
window.cornerstoneTools.freehand.deactivate(element, 1); // 画笔
window.cornerstoneTools.pan.deactivate(element, 1); // 允许平移
window.cornerstoneTools.panTouchDrag.deactivate(element); // 拖拽-移动
window.cornerstoneTools.probe.deactivate(element, 1); // 探索
window.cornerstoneTools.probeTouch.deactivate(element); // 探索并标注所处坐标数据
window.cornerstoneTools.zoomTouchDrag.deactivate(element); // 拖拽并放大
window.cornerstoneTools.length.deactivate(element); // 长度
window.cornerstoneTools.lengthTouch.deactivate(element); // 长度记录
window.cornerstoneTools.ellipticalRoi.deactivate(element, 1); // 椭圆
window.cornerstoneTools.ellipticalRoiTouch.deactivate(element); // 画圆/椭圆
window.cornerstoneTools.rectangleRoi.deactivate(element, 1); // 矩形
window.cornerstoneTools.rectangleRoiTouch.deactivate(element); // 画矩形
window.cornerstoneTools.angleTouch.deactivate(element); // 画角
window.cornerstoneTools.angle.deactivate(element, 1); // 角度
window.cornerstoneTools.arrowAnnotate.deactivate(element, 1); // 箭头注解
window.cornerstoneTools.arrowAnnotateTouch.deactivate(element); // 箭头
window.cornerstoneTools.rotateTouchDrag.deactivate(element); // 自由旋转
window.cornerstoneTools.wwwcTouchDrag.deactivate(element); // Drag灰度值与数据值调整
window.cornerstoneTools.wwwcTouchDrag.disable(element); // 关闭灰度值
window.cornerstone.setViewport(element, {
invert: false, // 正负片-负像
vflip: false, // 垂直翻转
hflip: false, // 水平翻转
});
// 是否开启
window.cornerstoneTools.zoomWheel.activate(element); // 缩放
if (name === 'panTouchDrag') {
window.cornerstoneTools.pan.activate(element, 1); // 允许平移
window.cornerstoneTools.panTouchDrag.activate(element); // 拖拽-移动
}
if (name === 'probe') {
window.cornerstoneTools.probe.activate(element, 1); // 探索
window.cornerstoneTools.probeTouch.activate(element); // 探索并标注所处坐标数据
}
if (name === 'zoomTouchDrag') {
window.cornerstoneTools.zoomWheel.deactivate(element); // 关闭缩放
window.cornerstoneTools.zoom.activate(element, 1); // 允许定点缩放
window.cornerstoneTools.zoomTouchDrag.activate(element); // 拖拽并放大
}
if (name === 'length') {
window.cornerstoneTools.freehand.activate(element, 1); // 画笔
window.cornerstoneTools.length.activate(element); // 长度
window.cornerstoneTools.lengthTouch.activate(element); // 长度记录
}
if (name === 'ellipticalRoi') {
window.cornerstoneTools.ellipticalRoi.activate(element, 1); // 椭圆
window.cornerstoneTools.ellipticalRoiTouch.activate(element); // 画圆/椭圆
}
if (name === 'rectangleRoi') {
window.cornerstoneTools.rectangleRoi.activate(element, 1); // 矩形
window.cornerstoneTools.rectangleRoiTouch.activate(element); // 画矩形
}
if (name === 'angle') {
window.cornerstoneTools.angleTouch.activate(element); // 画角
window.cornerstoneTools.angle.activate(element, 1); // 角度
}
if (name === 'arrowAnnotate') {
window.cornerstoneTools.arrowAnnotate.activate(element, 1); // 箭头注解
window.cornerstoneTools.arrowAnnotateTouch.activate(element); // 箭头
}
if (name === 'rotateTouchDrag') {
window.cornerstoneTools.rotateTouchDrag.activate(element); // 自由旋转
}
if (name === 'wwwcTouchDrag') {
window.cornerstoneTools.wwwc.activate(element, 1); // 允许开启灰度值
window.cornerstoneTools.wwwcTouchDrag.enable(element); // 开启灰度值
window.cornerstoneTools.wwwcTouchDrag.activate(element); // Drag灰度值与数据值调整
}
window.cornerstone.setViewport(element, {
invert: name === 'invert', // 正负片-负像
vflip: name === 'vflip', // 垂直翻转
hflip: name === 'hflip', // 水平翻转
});
};
const previousPage = async () => {
if (num === 0) {
commonUtils.alert('第一页');
} else {
num--;
}
await dicomParser();
cornerstoneSwitch('newLoad');
data.isShrink = true;
};
const nextPage = async () => {
if (props.visitId) {
if (num === imgUrl.length - 1) {
commonUtils.alert('最后一页');
} else {
num++;
}
await dicomParser();
cornerstoneSwitch('newLoad');
} else {
commonUtils.alert('最后一页');
}
data.isShrink = true;
};
const checkFunction = (index: number, name: string) => {
data.checkedChildIndex = index;
data.isShrink = true;
cornerstoneSwitch(name);
};
const checkedMenu = (index: number) => {
data.checkedIndex = index;
data.isShrink = false;
data.checkedChildIndex = -1;
};
const allData = toRefs(data);
onMounted(() => {
if (props.mediaUrl || props.visitId) {
dicomParser();
}
});
return {
imgUrl,
previousPage,
nextPage,
...allData,
checkFunction,
checkedMenu,
getImageSrc: commonUtils.getImageSrc,
};
},
});
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 80vh;
background-color: white;
}
#medical-imaging {
height: 65vh;
margin: 2rem;
background-color: rgb(8, 8, 8);
}
.foot {
padding: 1rem 2rem;
width: 100%;
height: 5rem;
display: flex;
justify-content: space-around;
align-items: center;
margin-bottom: 2rem;
button {
background: #fff;
font-size: 1.8rem;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold;
color: #3aa0ff;
line-height: 1.8rem;
width: 15.2rem;
text-align: center;
height: 4.4rem;
line-height: 4.4rem;
border-radius: 2.8rem;
opacity: 1;
border: 0.1rem solid #3aa0ff;
}
}
.meun-list {
width: 100%;
display: flex;
flex-wrap: wrap;
font-size: 1.4rem;
padding: 1rem 2rem;
color: #666666;
position: relative;
background: black;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: 400;
}
.meun-title {
margin-left: 1rem;
line-height: 1.9rem;
border: 1px solid transparent;
padding: 0 0.4rem;
&:first-child {
margin-left: 0;
}
}
.active-menu-title {
border: 1px solid #3aa0ff;
border-radius: 0.3rem;
color: #3aa0ff;
}
.meun-content {
width: 100%;
height: auto;
overflow: auto;
display: flex;
flex-wrap: wrap;
background: black;
position: absolute;
top: 4rem;
left: 0;
}
.button-part {
width: 25%;
padding: 1rem 0;
font-size: 1.3rem;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: 400;
div {
margin: 0 auto;
text-align: center;
img {
width: 3rem;
height: 3rem;
}
}
}
.checked {
background: #999;
color: black;
}
.shrink-btn {
position: absolute;
top: 1rem;
right: 1rem;
}
</style>