cornerstone 庫地址
需要用到的依賴庫愧捕,可 npm 可自行加入項(xiàng)目public 文件夾中谜悟,這里提供文件下載
點(diǎn)此下載 密碼: tcg3
注意(坑)
cornerstoneWADOImageLoader.js 文件中需要自行修改 path 路徑(注意:是絕對路徑哦)饥瓷,大概在 1750 行舷丹。當(dāng)時(shí)卡了好久氓奈。
var defaultConfig = {
maxWebWorkers: navigator.hardwareConcurrency || 1,
startWebWorkersOnDemand: true,
webWorkerPath: '/models/js/cornerstoneWADOImageLoaderWebWorker.js',//此路徑需要自行修改
webWorkerTaskPaths: [],
taskConfiguration: {
decodeTask: {
loadCodecsOnStartup: true,
initializeCodecsOnStartup: false,
codecsPath: '/models/js/cornerstoneWADOImageLoaderCodecs.js',//此路徑需要自行修改
usePDFJS: false,
strict: options.strict
}
}
};
寫在前面
我只介紹了 cornerstone 的一些基本用法翘魄,具體如何在項(xiàng)目中應(yīng)用,還是要靈活使用舀奶,例如我在項(xiàng)目中使用是先通過遞歸來緩存了所有的圖像再逐個(gè)展示暑竟,節(jié)省了加載的時(shí)間;通過算法分析的結(jié)節(jié)坐標(biāo)信息在圖像上繪制結(jié)節(jié)等育勺。如果需要幫助可留言但荤。碼字不易,研究不易涧至,如需轉(zhuǎn)載請注明出處腹躁。
準(zhǔn)備工作完畢,開始引入組件中
* 需要安裝的插件
* npm install --save dicom-parser //這個(gè)需要安裝
*/
// import Hammer from 'hammerjs';//移動端手勢插件 npm install hammerjs --save //選用南蓬,不需要移動端可不用
import * as cornerstone from '../../public/models/js/cornerstone';
import * as cornerstoneTools from '../../public/models/js/cornerstoneTools.js';
import * as cornerstoneWADOImageLoader from '../../public/models/js/cornerstoneWADOImageLoader';
/*
* cornerstoneMath.min.js文件 import 始終報(bào)錯(cuò)纺非,無奈哑了,最終在 index.html中加入解決,原因未知烧颖,知道的大佬可以告知一下
* <script src="./models/js/cornerstoneMath.min.js"></script>
*/
?
cornerstoneTools.external.cornerstone = cornerstone;
// cornerstoneTools.external.Hammer = Hammer;
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
?
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
cornerstoneWADOImageLoader.external.cornerstoneMath = cornerstoneMath;
初始化
<template>
<div id="DICOM" ref='dicom_canvas'></div>
</template>
......
init(){
let element=this.$refs.dicom_canvas;//獲取 dicom 元素節(jié)點(diǎn)
cornerstone.enable(element);//啟用節(jié)點(diǎn)
window.addEventListener('resize',function(e){//自適應(yīng)窗口
cornerstone.resize(element,true)
})
}
載入影像數(shù)據(jù)
start(){
cornerstone.loadAndCacheImage('http:XXXXXXXX.dcm').then((image)=>{//加載并緩存數(shù)據(jù)
cornerstone.displayImage(element,image)//展示 dicom弱左,參數(shù) 1:element 元素,參數(shù) 2:image
this.getImageInfo(image);//獲取圖片信息
}).catch((err)=>console.log(err))
}
cornerstoneimagerendered事件(重要?换础)
每當(dāng)圖像被cornerstone重新繪制時(shí)拆火,將發(fā)出CornerstoneImageRendered事件調(diào)用。這個(gè)事件包括可以使用HTML5 canvas上下文(例如幾何圖形或文本)在圖像上繪制的信息涂圆。你也可以更新HTML覆蓋與各種視口屬性们镜,如窗口寬度,窗口級別和縮放乘综。
......
element.addEventListener('cornerstoneimagerendered',function(e){
let eventData=e.detail;
this.getViewPort(eventData);//獲取當(dāng)前圖片視口信息
})
getViewPort(eventData){
this.imageInfo.windowWidth=Math.round(eventData.viewport.voi.windowWidth);//窗寬
this.imageInfo.windowCenter=Math.round(eventData.viewport.voi.windowCenter);//窗位
this.imageInfo.scale=parseInt(10 * eventData.viewport.scale);//縮放等級
}
getImageInfo(image){
this.imageInfo.seriesNumber=image.data.string('x00200011');//圖像序列號
this.imageInfo.imageNum=image.data.string('x00200013');//圖像位置
this.imageInfo.imageDate=image.data.string("x00080021");//拍攝日期
this.imageInfo.sliceThickness=image.data.string('x00180050');//層厚
this.imageInfo.patientId=image.data.string('x00100020');//病理號
// 判斷窗寬窗位是否合法
this.pixelR = image.data.uint16('x00280103');
this.heightBit = image.data.uint16('x00280102') || '';
// 病人基本信息
this.patientName = image.data.string('x00100010');
this.patientBirthDate = image.data.string('x00100030');
this.patientID = image.data.string('x00100020');
this.patientGender = image.data.string('x00100040');
this.sID = image.data.string('x00200011');
// 像素間距
this.pixelSpacing = image.data.string('x00280030');
this.imagePixelSpacing = image.data.string('x00181164') || '';
this.rowPixelSpacing = image.rowPixelSpacing;
// 放射放大系數(shù)
this.magnification = Number(image.data.string('x00181114'));
// 放射源到面板的距離
this.sourceTOdetector = image.data.string('x00181110');
// 放射源到病人的距離
this.sourceTOpatient = image.data.string('x00181111');
//this.modalityLUT = cornerstone.metaData.get('modalityLutModule', image.imageId).modalityLUTSequence;
this.voiContent = cornerstone.metaData.get('voiLutModule', image.imageId);
// 斜率截距
this.rescaleIntercept = Number(image.data.string('x00281052'));
this.rescaleSlope = Number(image.data.string('x00281053'));
}
cornerstoneTools (工具)
// 啟用工具
/*
數(shù)字:1 代表鼠標(biāo)左鍵憎账;2 代表鼠標(biāo)中鍵;4 代表鼠標(biāo)右鍵
可逐一試驗(yàn)功能
*/
cornerstoneTools.mouseInput.enable(this.element);//啟動鼠標(biāo)按下事件
enableAllTools() {
cornerstoneTools.wwwc.activate(element);
cornerstoneTools.pan.activate(element, 2);
cornerstoneTools.zoom.activate(element, 1);
cornerstoneTools.probe.activate(element, 1);
cornerstoneTools.length.activate(element, 1);
cornerstoneTools.ellipticalRoi.activate(element, 1);
cornerstoneTools.rectangleRoi.activate(element, 1);
cornerstoneTools.angle.activate(element, 1);
cornerstoneTools.highlight.activate(element, 1);
cornerstoneTools.freehand.activate(element, 1);
cornerstoneTools.stackScroll.activate(element);
cornerstoneTools.arrowAnnotate.activate(element, 1);
cornerstoneTools.freehand.activate(element, 1);
// touch
cornerstoneTools.wwwcTouchDrag.deactivate(element);
cornerstoneTools.probeTouch.deactivate(element);
cornerstoneTools.panTouchDrag.deactivate(element);
cornerstoneTools.zoomTouchDrag.deactivate(element);
cornerstoneTools.lengthTouch.deactivate(element);
cornerstoneTools.ellipticalRoiTouch.deactivate(element);
cornerstoneTools.rectangleRoiTouch.deactivate(element);
cornerstoneTools.angleTouch.deactivate(element);
cornerstoneTools.stackScrollTouchDrag.deactivate(element);
cornerstoneTools.arrowAnnotateTouch.deactivate(element);
cornerstoneTools.rotateTouchDrag.deactivate(element);
cornerstoneTools.rotateTouch.disable(element);
}
// 停用工具 // before making a new tool active
disableAllTools() {
cornerstoneTools.wwwc.disable(element);
cornerstoneTools.pan.deactivate(element, 2);
cornerstoneTools.zoom.deactivate(element, 1);
cornerstoneTools.probe.deactivate(element, 1);
cornerstoneTools.length.deactivate(element, 1);
cornerstoneTools.ellipticalRoi.deactivate(element, 1);
cornerstoneTools.rectangleRoi.deactivate(element, 1);
cornerstoneTools.angle.deactivate(element, 1);
cornerstoneTools.highlight.deactivate(element, 1);
cornerstoneTools.freehand.deactivate(element, 1);
cornerstoneTools.stackScroll.deactivate(element);
cornerstoneTools.arrowAnnotate.deactivate(element, 1);
cornerstoneTools.freehand.deactivate(element, 1);
// touch
cornerstoneTools.wwwcTouchDrag.deactivate(element);
cornerstoneTools.probeTouch.deactivate(element);
cornerstoneTools.panTouchDrag.deactivate(element);
cornerstoneTools.zoomTouchDrag.deactivate(element);
cornerstoneTools.lengthTouch.deactivate(element);
cornerstoneTools.ellipticalRoiTouch.deactivate(element);
cornerstoneTools.rectangleRoiTouch.deactivate(element);
cornerstoneTools.angleTouch.deactivate(element);
cornerstoneTools.stackScrollTouchDrag.deactivate(element);
cornerstoneTools.arrowAnnotateTouch.deactivate(element);
cornerstoneTools.rotateTouchDrag.deactivate(element);
cornerstoneTools.rotateTouch.disable(element);
}
改變窗寬窗位
windowChange(index){
/*
* index=1 ww:default,wl:default
* index=2 ww:1500,wl:-450
* index=3 ww:250,wl:30
* index=4 ww:1000,wl:250
* index=5 ww:300,wl:40
*/
let viewportDefault = cornerstone.getDefaultViewportForImage(element, image);//獲取當(dāng)前圖像默認(rèn)的窗寬窗位
// console.log(viewportDefault.voi.windowWidth,viewportDefault.voi.windowCenter)
let viewport = cornerstone.getViewport(this.element);
viewport.voiLUT = undefined;
?
?
if(index==1){
viewport.voi.windowWidth = viewportDefault.voi.windowWidth;
viewport.voi.windowCenter = viewportDefault.voi.windowCenter;
}else if(index==2){
viewport.voi.windowWidth = 1500;
viewport.voi.windowCenter = -450;
}else if(index==3){
viewport.voi.windowWidth = 250;
viewport.voi.windowCenter = 30;
}else if(index==4){
viewport.voi.windowWidth = 1000;
viewport.voi.windowCenter = 250;
}else if(index==5){
viewport.voi.windowWidth = 300;
viewport.voi.windowCenter = 40;
}
cornerstone.setViewport(this.element, viewport);//調(diào)節(jié)窗寬窗位
},
鼠標(biāo)滾輪切換圖像
/*鼠標(biāo)滾輪事件 */
mousewheelChange(){
let _this=this;
const wheelEvents = ['mousewheel', 'DOMMouseScroll'];
wheelEvents.forEach((eventType) => {
this.element.addEventListener(eventType, this.mousewheelHandle);
});
},
mousewheelHandle(e){
let _this=this;
// Firefox e.detail > 0 scroll back, < 0 scroll forward
// chrome/safari e.wheelDelta < 0 scroll back, > 0 scroll forward
if (e.wheelDelta < 0 || e.detail > 0) {//向下滾動
_this.currentImageIndex++;
if(_this.currentImageIndex>_this.nowSeries.length-1){
_this.currentImageIndex=0
}
} else {//向上滾動
_this.currentImageIndex--;
if(_this.currentImageIndex<0){
_this.currentImageIndex=_this.nowSeries.length-1
}
}
_this.updateTheImage(_this.currentImageIndex);//根據(jù) ID 索引切換圖像
?
// 防止頁面滾動
return false;
},
其他功能
// set the canvas context to the image coordinate system(將畫布上下文設(shè)置為圖像坐標(biāo)系統(tǒng))
//繪制前調(diào)用
cornerstone.setToPixelCoordinateSystem(eventData.enabledElement, eventData.canvasContext);
?
//坐標(biāo)轉(zhuǎn)換
cornerstone.pageToPixel(element, X, Y)//將像素坐標(biāo)轉(zhuǎn)為圖像坐標(biāo)卡辰,返回x,y對象
?
//更新圖像
cornerstone.updateImage(element);
?
//清除緩存
cornerstone.imageCache.purgeCache();
cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.purge();
cornerstoneWADOImageLoader.wadouri.fileManager.purge();
?
//查看緩存
const cacheInfo = cornerstone.imageCache.getCacheInfo();