影像云胶片:Dicom纯js的三维重建影像阅片器
影像云胶片主要:通过浏览器浏览Dicom影像阅片,通过多终端设备(如电脑、平板、手机),为医生、患者及其他授权人员提供随时随地的影像调阅功能,打破时间和空间限制。同时,支持影像数据在不同医疗机构之间的安全共享,促进医疗协作与远程会诊的开展。主要功能:
- 支持标准DIcom影像的2D浏览,预设窗位,伪彩,序列间,序列内多种布局方式。
- 影像处理,提供影像翻图、缩放、移动、透镜、反相、旋转、截图等操作
- 影像测量,提供箭头、直线、十字架、角度、Cobb、心胸比、椭圆、矩形、勾画,橡皮擦、CT值等数据的测量
- 支持影像的三维重建,包括多平面重建,容积漫游技术(VR)、最大/小密度投影等功能
- 支持影像胶片打印功能,包括DR,CT等胶片自定义布局打印
- 支持平板,手机等移动设备的影像浏览
总体架构:BS(浏览器/服务器)架构
-
前端:基于HTML5、WebGL技术开发,无需安装插件,支持PC浏览器、手机H5、微信小程序、支付宝小程序等多种终端。
-
后端:后端居于fo-dicom组件进行开发,对dicom文件访问授权服务,访问MD5签名验证等身份验证。
核心技术栈
-
影像渲染引擎:使用 VTK.js 等开源框架,实现基于WebGL的高性能二维、三维影像渲染。
-
DICOM服务:自研或使用开源组件(如fo-dicom)实现DICOM文件的接收(C-Store)、查询(C-Find)、检索(C-Move)等服务。
主要代码示例
1:前端采用有vue3+element-ui进行开发,检查屏幕大小,以便适应不同的屏幕
<script setup> import LeftSeriesMobile from './views/LeftSeriesMobile.vue' import CenterImage from './views/CenterImage.vue' import RightToolMobile from './views/RightToolMobile.vue' import { ElMessageBox } from 'element-plus' // 注册resize事件监听器 调整laytou大小 window.addEventListener('resize', function (evt) { if (window.innerWidth > 768) { ElMessageBox.alert("系统检测到你在阅片期间对浏览器进行了缩放。为防止图像显示及测量工作不精确,强烈建议您重新打开影像!"); } }); </script> <template> <div class="divRightMb"> <RightToolMobile /> </div> <div class="divCenterMb" id="divCenter"> <CenterImage /> </div> <div class="divLeftMb"> <LeftSeriesMobile /> </div> </template> <style scoped></style>
最终在PC端和手机端效果图如下:


2:使用VTK.js 等开源框架,实现基于WebGL的高性能二维、三维影像渲染。
//初始化一个视窗 function ViewGridChange_LoadDicom_OneView(layout, element, showSeries) { //注册事件 element.addEventListener(IMAGE_RENDERED, IMAGE_RENDERED_CallBack); layout.ShowSeries = showSeries;//当前窗体显示的序列对象 element.ShowSeries = showSeries;//当前窗体显示的序列对象 let viewport; if (showSeries.SeriesItemType == 1) { viewport = { viewportId: layout.viewportId, type: showSeries.viewType, element: element } element.addEventListener(STACK_NEW_IMAGE, STACK_NEW_IMAGE_CallBack); } else { viewport = { viewportId: layout.viewportId, type: showSeries.viewType, element: element, defaultOptions: { orientation: showSeries.orientation }, } element.addEventListener(VOLUME_NEW_IMAGE, VOLUME_NEW_IMAGE_CallBack); } return viewport; }
3:实现三维十字准线工具的功能
View Code
三维重建效果如图所示:


4:胶片打印布局设置相关代码
//设置中间图像大小 let curGolb_PaperSize = "";//当前纸张大小 let curGolb_Direction = "";//当前方向 let curGolb_ShowScale = "1";//当前显示比例 function CenterSetImageSize(paperSize, direction, showScale, isPrint) { SetImageSizeisPrint = isPrint; if (isEmpty(paperSize)) paperSize = curGolb_PaperSize; if (isEmpty(direction)) direction = curGolb_Direction; if (isEmpty(showScale)) showScale = curGolb_ShowScale; if (curGolb_PaperSize == paperSize && curGolb_Direction == direction && curGolb_ShowScale == showScale) { return; } curGolb_PaperSize = paperSize; curGolb_Direction = direction; curGolb_ShowScale = showScale; //根据纸张大写设置图像大小 let paperObj = null; for (let i = 0; i < PaperSizeArys.length; i++) { const item = PaperSizeArys[i]; if (item.value == paperSize) { paperObj = item; break; } } if (!paperObj) return; //设置图像大小 let imgWidth = 0; let imgHeight = 0; if (direction == "0") {//横向 imgWidth = paperObj.ImgHeight; imgHeight = paperObj.ImgWidth; } else {//纵向 imgWidth = paperObj.ImgWidth; imgHeight = paperObj.ImgHeight; } let imgWidthPx = imgWidth * 96; let imgHeightPx = imgHeight * 96; let scaleFloat = 1; if (showScale == "-2") {//自适应宽高 const rect = divImgElemet.parentElement.getBoundingClientRect(); //如果宽或者高 任意一个大于了外层容器 则进行缩放 if (imgWidthPx > rect.width || imgHeightPx > rect.height) { //如果宽超出的范围更大,则以宽为基准进行缩放 if (imgWidthPx - rect.width >= imgHeightPx - rect.height) { scaleFloat = rect.width / imgWidthPx; } else { //以高位基准进行缩放 scaleFloat = rect.height / imgHeightPx; } scaleFloat = scaleFloat * 0.98;//自适应时设置图像显示比例98%,防止出现滚动条 } } else if (showScale == "-1") {//自适应宽 const rect = divImgElemet.parentElement.getBoundingClientRect(); //如果宽或者高 任意一个大于了外层容器 则进行缩放 if (imgWidthPx > rect.width) { //如果宽超出的范围更大,则以宽为基准进行缩放 scaleFloat = rect.width / imgWidthPx * 0.98;//自适应时设置图像显示比例98%,防止出现滚动条 } } else { scaleFloat = parseFloat(showScale); } imgWidth = numToFixed(imgWidth * scaleFloat, 0) + "in"; imgHeight = numToFixed(imgHeight * scaleFloat, 0) + "in"; if (imgWidth == divImgElemet.style.width && imgHeight == divImgElemet.style.height) { //图像大小不变,如果是打印则直接执行打印 if (SetImageSizeisPrint == true) { PrintCurrentPage(false); } } else { divImgElemet.style.width = imgWidth; divImgElemet.style.height = imgHeight; //设置图像上字体大小 let dfontSieze = 11; if (!isEmpty(PrintConfigObj.FontSize)) { dfontSieze = parseInt(PrintConfigObj.FontSize); } const setFontSize = numToFixed(dfontSieze * scaleFloat, 2) + "px";//标注字体为11px,乘以缩放比例 divImgElemet.style.fontSize = setFontSize; //获取元素像素大小 document.querySelector("#spShowImgSizePx").innerHTML = divImgElemet.scrollWidth + "×" + divImgElemet.scrollHeight; } }
胶片打印布局效果如图

技术交流沟通联系QQ:343798739;469116292

浙公网安备 33010602011771号