vue使用医学影像cornerstone展示nifti文件
首先 npm install cornerstone-core cornerstone-math
<template>
<div class="nifti-image-container">
<div style="position: relative;" v-for="item in dicomList" :key="item.id" oncontextmenu="return false"
unselectable="on" onselectstart="return false;" onmousedown="return false;">
<div class="dicom-info ">
<span>{{ item.currImgIdIndex + 1 }} / {{ item.total }}</span>
</div>
<div ref="viewports" class="nifti-image" :id="item.id"></div>
</div>
<!-- <div id="nifti-image" class="nifti-image" ref='dicom_canvas'></div> -->
</div>
</template>
<script>
var loaded = false
const Tools = ["OrientationMarkers", "Pan", "Zoom"];
const synchronizer = new cornerstoneTools.Synchronizer(
"cornerstonenewimage",
cornerstoneTools.updateImageSynchronizer
);
import * as cornerstone from 'cornerstone-core'
import * as cornerstoneMath from 'cornerstone-math'
import * as Hammerjs from 'hammerjs'
import * as cornerstoneTools from 'cornerstone-tools'
import * as cornerstoneNIFTIImageLoader from 'cornerstone-nifti-image-loader'
export default {
data() {
return {
ImageId: "",
loaded: false,
dicomList: [{
id: "nifti-image-z",
axis: "z",
currImgIdIndex: 0,
total: 0,
complete: false,
scale: 0,
overlayUrl: "",
overlayPixels: [],
},
{
id: "nifti-image-x",
axis: "x",
currImgIdIndex: 0,
total: 0,
complete: false,
scale: 0,
overlayUrl: "",
overlayPixels: [],
},
{
id: "nifti-image-y",
axis: "y",
currImgIdIndex: 0,
total: 0,
complete: false,
scale: 0,
overlayUrl: "",
overlayPixels: [],
},
]
}
},
props: {
Select_url: {
type: [String, Number],
default: "http://localhost:3000/avg152T1_LR_nifti.nii", //默认值为空现在测试阶段
},
},
watch: {
Select_url: {
handler(val) {
this.display();
},
}
},
mounted() {
cornerstoneNIFTIImageLoader.external.cornerstone = cornerstone;
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
cornerstoneTools.external.cornerstone = cornerstone;
cornerstoneTools.external.Hammer = Hammer;
cornerstoneNIFTIImageLoader.nifti.streamingMode = true;
this.ImageId = cornerstoneNIFTIImageLoader.nifti.ImageId;
cornerstoneTools.init();
const element = document.getElementById('nifti-image');
this.$refs.viewports.forEach((element) => {
element.addEventListener("cornerstonetoolsmousewheel", (e) => {
e.preventDefault()
this.$nextTick(() =>{
this.handleStackScroll(e)
});
});
// render事件
element.addEventListener(cornerstone.EVENTS.IMAGE_RENDERED, (e) => {
e.preventDefault()
this.$nextTick(() => {
this.handleEnabled(e)
});
});
});
this.display()
},
methods: {
async display(){
let timepoint = 0;
let url=window.SITE_CONFIG.baseUrl + "/static"+ this.Select_url;
for (let i = 0; i < this.dicomList.length; i++) {
const canvas = document.getElementById(this.dicomList[i].id);
console.log(this.Select_url);
const imageIdObject = this.ImageId.fromURL("nifti:" +
`${url}#${this.dicomList[i].axis},t-${timepoint}`);
await this.loadAndViewImage(
canvas,
`nifti:${imageIdObject.filePath}#${this.dicomList[i].axis},t-${timepoint}`,
i
);
}
this.$emit('current-loaded')
},
handleStackScroll(e) {
// 滚动事件
const element = e.detail.element;
const toolData = cornerstoneTools.getToolState(element, "stack");
const stackData = toolData.data[0];
let currImgIdIndex = stackData.currentImageIdIndex;
let dicom = this.dicomList.find((item) => item.id === element.id);
dicom.currImgIdIndex = currImgIdIndex;
},
handleEnabled(e) {
// render事件
const viewport = e.detail.viewport;
const element = e.detail.element;
const toolData = cornerstoneTools.getToolState(element, "stack");
const stackData = toolData.data[0];
let dicom = this.dicomList.find((item) => item.id === element.id);
dicom.scale = viewport.scale.toFixed(4);
dicom.currImgIdIndex = stackData.currentImageIdIndex;
},
loadAndViewImage(element, imageId, i) {
cornerstone.enable(element);
const _this = this;
const imageIdObject = this.ImageId.fromURL(imageId);
element.dataset.imageId = imageIdObject.url;
return new Promise((resolve) => {
try {
cornerstone.loadAndCacheImage(imageIdObject.url).then(function(image) {
// 设置图片信息
let imagePlaneModule = cornerstone.metaData.get(
"imagePlaneModule",
image.imageId
);
resolve(image);
const numberOfSlices = cornerstone.metaData.get(
"multiFrameModule",
imageIdObject.url
).numberOfFrames;
const imageIds = Array.from(
Array(numberOfSlices),
(_, i) =>
`nifti:${imageIdObject.filePath}#${imageIdObject.slice.dimension}-${i},t-0`
);
const stack = {
currentImageIdIndex: imageIdObject.slice.index,
imageIds,
};
const viewport = cornerstone.getDefaultViewportForImage(element, image);
// 像素渲染
const enabledElement = cornerstone.getEnabledElement(element);
_this.dicomList[i]["total"] = imageIds.length;
cornerstone.displayImage(element, image, viewport);
cornerstone.resize(element, true);
enabledElement.viewport.pixelReplication = true;
cornerstoneTools.addStackStateManager(element, ["stack", "Crosshairs"]);
cornerstoneTools.addToolState(element, "stack", stack);
// 设置 Pan、Zoom、Orient工具
Tools.forEach((tool) => {
let key = tool === "Pan" ? 2 : 1;
cornerstoneTools.addToolForElement(
element,
cornerstoneTools[`${tool}Tool`]
);
cornerstoneTools.setToolActive(tool, {
mouseButtonMask: key,
});
});
// 鼠标滑动
cornerstoneTools.addToolForElement(
element,
cornerstoneTools["StackScrollMouseWheelTool"]
);
cornerstoneTools.setToolActive("StackScrollMouseWheel", {
mouseButtonMask: 0,
});
synchronizer.add(element);
// 十字线
cornerstoneTools.stackPrefetch.enable(element);
cornerstoneTools.addToolForElement(
element,
cornerstoneTools.ReferenceLinesTool
);
cornerstoneTools.setToolEnabled("ReferenceLines", {
synchronizationContext: synchronizer,
});
// 光标
cornerstoneTools.addToolForElement(
element,
cornerstoneTools["CrosshairsTool"]
);
cornerstoneTools.setToolActive("Crosshairs", {
mouseButtonMask: 1,
synchronizationContext: synchronizer,
});
});
} catch (err) {
throw err;
}
});
},
},
}
</script>
<style scoped>
.nifti-image-container{
display: flex;
flex-flow: row wrap;
width: 100%;
height: auto;
}
.nifti-image {
margin: 30px 10px 10px 20px;
width: 400px;
height: 200px;
}
.dicom-info{
color: #FFFFFF;
position: absolute;
bottom: 20px;
left: 40px;
z-index: 11;
}
</style>
github cornerstonejs地址
…/dist/cornerstoneNIFTIImageLoader.js文件可以去cornerstone.js的github中去找这个demo