//功能名称 const functionNames = [ "Magnify", "Pan", "Zoom", "ZoomMouseWheel", "Wwwc", "ScaleOverlay", "OrientationMarkers", "WwwcRegion", "Rotate", "Angle", "ArrowAnnotate", "Bidirectional", "CobbAngle", "EllipticalRoi", "FreehandRoi", "Length", "Probe", "RectangleRoi", "TextMarker", "StackScroll", "StackScrollMouseWheel" ] //标尺和方向显示可与其他状态同时启用 const displayFunctions = ["ScaleOverlay", "OrientationMarkers"] //不能同时启用的功能 const notNeedDisableFunctions = ["WwwcRegion", "Rotate", "Angle", "ArrowAnnotate", "Bidirectional", "CobbAngle", "EllipticalRoi", "FreehandRoi", "Length", "Probe", "RectangleRoi", "TextMarker"] //状态数据 var stateData = { rowCount: 1, columnCount: 1, imgIndex: 0, element: {}, dicomInfo: {}, showMapping: new Map() } /*切换工具*/ function switchAction(tagName, flag, btn) { //btn btn-primary var isSelected = $(btn).hasClass('selected'); if (isSelected) { $(btn).removeClass("btn-primary") $(btn).removeClass("selected") $(btn).addClass("btn-default") disableFunctions(tagName); } else { disableFunctions(tagName); $(btn).removeClass("btn-default") $(btn).addClass("btn-primary") $(btn).addClass("selected") } if (!isSelected) { cornerstoneTools.setToolActive(tagName, { mouseButtonMask: 1 }) } } function reload() { var data = cornerstoneTools.getToolState(stateData.element, "stack").data[0]; var index = data.currentImageIdIndex; var imgId = data.imageIds[index]; data.currentImageIdIndex = index; cornerstone.loadAndCacheImage(imgId).then(function (image) { cornerstone.enable(stateData.element); cornerstone.displayImage(stateData.element, image); }); } //下一张 function next(imgId) { if (imgId && stateData.element != imgId) { return; } var data = cornerstoneTools.getToolState(stateData.element, "stack").data[0]; var index = data.currentImageIdIndex; if (index == data.imageIds.length - 1) { return; } else { index += 1; } var imgId = data.imageIds[index]; data.currentImageIdIndex = index; cornerstone.loadAndCacheImage(imgId).then(function (image) { cornerstone.enable(stateData.element); cornerstone.displayImage(stateData.element, image); renderTagText(stateData.element,image) }); for (var i = 0; i < 10; i++) { if (index + i == data.imageIds.length - 1) { break; } cornerstone.loadImage(data.imageIds[index + i]).then((image) => { console.log("loaded ok " + data.imageIds[index + i]); }) } setSliderValue(stateData.element.id) } //读取文件中的标签信息 function getDicomInfo(image) { var imageInfo = {}; imageInfo.seriesNumber = image.data.string('x00200011');//图像序列号 imageInfo.imageNum = image.data.string('x00200013');//图像位置 imageInfo.imageDate = image.data.string("x00080021");//拍摄日期 imageInfo.sliceThickness = image.data.string('x00180050');//层厚 imageInfo.patientId = image.data.string('x00100020');//病理号 // 判断窗宽窗位是否合法 imageInfo.pixelR = image.data.uint16('x00280103'); imageInfo.heightBit = image.data.uint16('x00280102') || ''; // 病人基本信息 imageInfo.patientName = image.data.string('x00100010'); imageInfo.patientBirthDate = image.data.string('x00100030'); imageInfo.patientGender = image.data.string('x00100040'); imageInfo.sID = image.data.string('x00200011'); // 像素间距 imageInfo.pixelSpacing = image.data.string('x00280030'); imageInfo.height = image.data.uint16('x00280010'); imageInfo.width = image.data.uint16('x00280011'); imageInfo.height = image.data.uint16('x00280010'); imageInfo.windowCenter = image.data.string('x00281050'); imageInfo.windowWidth = image.data.string('x00281051'); imageInfo.imagePixelSpacing = image.data.string('x00181164') || ''; imageInfo.rowPixelSpacing = image.rowPixelSpacing; // 放射放大系数 imageInfo.magnification = Number(image.data.string('x00181114')); // 放射源到面板的距离 imageInfo.sourceTOdetector = image.data.string('x00181110'); // 放射源到病人的距离 imageInfo.sourceTOpatient = image.data.string('x00181111'); //this.modalityLUT = cornerstone.metaData.get('modalityLutModule', image.imageId).modalityLUTSequence; imageInfo.voiContent = cornerstone.metaData.get('voiLutModule', image.imageId); // 斜率截距 imageInfo.rescaleIntercept = Number(image.data.string('x00281052')); imageInfo.rescaleSlope = Number(image.data.string('x00281053')); return imageInfo; } //上一张 function last(imgId) { if (imgId && stateData.element != imgId) { return; } var data = cornerstoneTools.getToolState(stateData.element, "stack").data[0]; var index = data.currentImageIdIndex; if (index == 0) { return; } else { index -= 1; } var imgId = data.imageIds[index]; data.currentImageIdIndex = index; cornerstone.loadAndCacheImage(imgId).then(function (image) { cornerstone.enable(stateData.element); cornerstone.displayImage(stateData.element, image); renderTagText(stateData.element, image) }); setSliderValue(stateData.element.id) } //进度条更新 function setAllSliderValue() { //获取所有已经加载的图片区映射关系 if (stateData.showMapping) { stateData.showMapping.forEach((value, key) => { setSliderValue(key); }); } } //标签文本更新 function setAllTagsValue() { if (stateData.showMapping) { stateData.showMapping.forEach((value, key) => { var element = document.getElementById(key) var image = cornerstone.getImage(element); //TODO 缺少获取图片对象信息 renderTagText(element, image) }); } } //重置画布 function resetRenderCanvase() { var element = stateData.element; const enabledElement = cornerstone.getEnabledElement(element); enabledElement.renderingTools.colormapId = undefined; enabledElement.renderingTools.colorLut = undefined; const renderCanvas = enabledElement.renderingTools.renderCanvas; const canvasContext = renderCanvas.getContext('2d'); // NOTE - we need to fill the render canvas with white pixels since we // control the luminance using the alpha channel to improve rendering performance. canvasContext.fillStyle = 'white'; canvasContext.fillRect(0, 0, renderCanvas.width, renderCanvas.height); const renderCanvasData = canvasContext.getImageData(0, 0, renderCanvas.width, renderCanvas.height); enabledElement.renderingTools.renderCanvasContext = canvasContext; enabledElement.renderingTools.renderCanvasData = renderCanvasData; cornerstone.updateImage(stateData.element); } //重置按钮状态 function resetBtnState(id) { if ($("#" + id).hasClass("selected")) { $("#" + id).removeClass("btn-primary") $("#" + id).removeClass("selected") $("#" + id).addClass("btn-default") } } function disableFunctions(currentFun) { functionNames.forEach(function (fname) { resetBtnState(fname) if (currentFun != fname && (notNeedDisableFunctions.includes(fname) || displayFunctions.includes(fname))) { return; } cornerstoneTools.setToolDisabled(fname, { mouseButtonMask: 1 }) }) } //辅助工具 const toolFunction = ["ScaleOverlay", "OrientationMarkers"] const wheelFunction = ["ZoomMouseWheel"] //撤销所有改动 function resetTool() { //反转色 //invert(null, $("#invert"), true) //changColor(0, $("#changeColor"), true) functionNames.forEach(function (fname) { if (notNeedDisableFunctions.includes(fname)) { cornerstoneTools.clearToolState(stateData.element, fname); } }) cornerstone.reset(stateData.element); cornerstone.updateImage(stateData.element); } //反转颜色 function invert(flag, btn, reset) { //btn btn-primary var isSelected = $(btn).hasClass('selected'); if (isSelected || reset) { $(btn).removeClass("btn-primary") $(btn).removeClass("selected") $(btn).addClass("btn-default") } else { $(btn).removeClass("btn-default") $(btn).addClass("btn-primary") $(btn).addClass("selected") } //反转颜色 var viewport = { invert: !isSelected ? true : false } cornerstone.setViewport(stateData.element, viewport); } //彩色 function changColor(flag, btn, reset) { var element = stateData.element; //btn btn-primary var isSelected = $(btn).hasClass('selected'); if (isSelected || reset) { $(btn).removeClass("btn-primary") $(btn).removeClass("selected") $(btn).addClass("btn-default") } else { $(btn).removeClass("btn-default") $(btn).addClass("btn-primary") $(btn).addClass("selected") } resetRenderCanvase(); const b = cornerstone.getEnabledElement(element) const v = cornerstone.getDefaultViewport(b.canvas, b.image) var vp = cornerstone.getViewport(element); vp.colormap = !isSelected ? "hsv" : undefined; if (!flag) { cornerstone.setViewport(element, v) } else { cornerstone.setViewport(element, vp) } } //重置cornerstone function reset() { cornerstone.reset(stateData.element); } function initConerstone(element) { // 注册并挂载cornerstone及其cornerstoneTools,固定操作 cornerstoneTools.external.cornerstone = cornerstone; cornerstoneTools.external.cornerstoneMath = cornerstoneMath; cornerstoneTools.external.Hammer = Hammer; cornerstoneWADOImageLoader.external.dicomParser = dicomParser; cornerstoneWADOImageLoader.external.cornerstone = cornerstone; // imageId就是cornerstone要求的.dcm图片地址,例如:var imageId = "wadouri:http://127.0.0.1:6699/ctdcm1.dcm"; //var imageId = "wadouri:./1.dcm"; // 初始化cornerstoneTools工具 cornerstoneTools.init(); //// 获取要用于加载图片的div区域 //element = document.getElementById('dicomImage'); ////激活获取到的用于图片加载的区域 cornerstone.enable(element); // 从cornerstoneTools库中获取窗宽,窗高工具 const WwwcTool = cornerstoneTools.WwwcTool; //添加获取到的窗宽,窗高工具 cornerstoneTools.addTool(WwwcTool); //放大 const MagnifyTool = cornerstoneTools.MagnifyTool; cornerstoneTools.addTool(MagnifyTool) //平移 const PanTool = cornerstoneTools.PanTool; cornerstoneTools.addTool(PanTool) const ZoomTool = cornerstoneTools.ZoomTool; cornerstoneTools.addTool(ZoomTool, { // Optional configuration configuration: { invert: false, preventZoomOutsideImage: false, minScale: .1, maxScale: 20.0, } }); const ZoomMouseWheelTool = cornerstoneTools.ZoomMouseWheelTool; cornerstoneTools.addTool(ZoomMouseWheelTool) const WwwcRegionTool = cornerstoneTools.WwwcRegionTool; cornerstoneTools.addTool(WwwcRegionTool) const ScaleOverlayTool = cornerstoneTools.ScaleOverlayTool; cornerstoneTools.addTool(ScaleOverlayTool) //旋转 const RotateTool = cornerstoneTools.RotateTool; cornerstoneTools.addTool(RotateTool) const OrientationMarkersTool = cornerstoneTools.OrientationMarkersTool; cornerstoneTools.addTool(OrientationMarkersTool) const AngleTool = cornerstoneTools.AngleTool; cornerstoneTools.addTool(AngleTool) const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool; cornerstoneTools.addTool(ArrowAnnotateTool) const BidirectionalTool = cornerstoneTools.BidirectionalTool; cornerstoneTools.addTool(BidirectionalTool) const CobbAngleTool = cornerstoneTools.CobbAngleTool; cornerstoneTools.addTool(CobbAngleTool) const EllipticalRoiTool = cornerstoneTools.EllipticalRoiTool; cornerstoneTools.addTool(EllipticalRoiTool) const FreehandRoiTool = cornerstoneTools.FreehandRoiTool; cornerstoneTools.addTool(FreehandRoiTool) const LengthTool = cornerstoneTools.LengthTool; cornerstoneTools.addTool(LengthTool) const ProbeTool = cornerstoneTools.ProbeTool; cornerstoneTools.addTool(ProbeTool) const RectangleRoiTool = cornerstoneTools.RectangleRoiTool; cornerstoneTools.addTool(RectangleRoiTool) const TextMarkerTool = cornerstoneTools.TextMarkerTool // set up the markers configuration const configuration = { markers: ['F5', 'F4', 'F3', 'F2', 'F1'], current: 'F5', ascending: true, loop: true, } cornerstoneTools.addTool(TextMarkerTool, { configuration }) const StackScrollTool = cornerstoneTools.StackScrollTool cornerstoneTools.addTool(StackScrollTool) const StackScrollMouseWheelTool = cornerstoneTools.StackScrollMouseWheelTool cornerstoneTools.addTool(StackScrollMouseWheelTool) cornerstoneTools.setToolActive('StackScrollMouseWheel', {}) } function initConerstoneAndData() { var series = stateData.dicomInfo.seriesList[stateData.imgIndex].instanceList const scheme = 'wadouri' const baseUrl = '' const imageIds = series.map(seriesImage => `${scheme}:${baseUrl}${seriesImage.imageid}`) //define the stack const stack = { currentImageIdIndex: 0, imageIds: imageIds } cornerstone.enable(stateData.element); // load images and set the stack cornerstone.loadImage(imageIds[0]).then((image) => { initSlider(stateData.element); cornerstone.displayImage(stateData.element, image) cornerstoneTools.addStackStateManager(stateData.element, ['stack']) cornerstoneTools.addToolState(stateData.element, 'stack', stack) renderTagText(stateData.element, image) }) } //页面加载完成,执行初始化 $(document).ready(function () { createElements(1, 1,true); //激活获取到的用于图片加载的区域 stateData.element = document.getElementById('dicomImage_0_0'); stateData.showMapping.set('dicomImage_0_0',0); //cornerstone.enable(stateData.element); initConerstone(stateData.element); //初始化数据 initData(); //鼠标滚轮事件 document.addEventListener('mousewheel', function (event) { // 处理事件 setAllSliderValue(); setAllTagsValue(); }); //鼠标移动事件 document.addEventListener('mousemove', function (event) { // 处理事件 setAllSliderValue(); setAllTagsValue(); }); }) //初始化右侧图片列表 function initImgList(data) { $("#dicom-list").empty(); for (var i = 0; i < data.seriesList.length; i++) { var className = "series_img"; if (stateData.imgIndex == i) { className += "_active"; } $("#dicom-list").append(''); $("#dicom-list").append('