cornerstoneTools鼠标左键显示信息

529 阅读1分钟

style

body{
        margin: 0;
        padding: 20px;
}
canvas{
        background-color: #000;
}
.info{
        position: fixed;
        right: 50px;
        top: 50%;
        transform: translateY(-50%);
        border-radius: 5px;
        background-color: #333;
        color: #fff;
        padding: 16px;
        max-width: 420px;
        word-break: break-all;
        max-height: 520px;
        overflow: hidden auto;
}
.info p{
        margin:5px 0;
}
.info span{
        font-size: 18px;
}
.draw-data{
        line-height: 1.6;
}

html

<p class="tools">
        <button data-tool="Angle">角度</button>
        <button data-tool="ArrowAnnotate">箭头</button>
        <button data-tool="RectangleRoi">矩形</button>
        <button data-tool="EllipticalRoi">椭圆形</button>
        <button data-tool="CircleRoi">圆形</button>
        <button data-tool="Bidirectional">双向测量</button>
        <button data-tool="CobbAngle">Cobb角</button>
        <button data-tool="FreehandRoi">手绘</button>
        <button data-tool="Length">长度测量</button>
        <button data-tool="Probe">探针</button>
        <button data-tool="TextMarker">标注</button>
</p>
<div id="dicomImage" oncontextmenu="return false" onmousedown="return false"></div>
<div class="info">
        <p>工具: <span class="tool"></span></p>
        <div class="data-wrap">
                <p>绘制数据:</p>
                <p class="draw-data"></p>
        </div>
        <p>图像ID: <span class="imgId"></span></p>
        <p>放大倍数: <span class="scale"></span></p>
        <p>水平翻转: <span class="hflip"></span></p>
        <p>垂直翻转: <span class="vflip"></span></p>
        <p>位移: <span class="translate"></span></p>
        <p>反白: <span class="invert"></span></p>
        <p>旋转度数: <span class="rotate"></span></p>
        <p>窗口中心: <span class="wc"></span></p>
        <p>窗宽: <span class="ww"></span></p>
        <p>voi : <span class="voi"></span></p>
</div>
<script src="https://unpkg.com/hammerjs@2.0.8/hammer.js"></script>
<script src="https://unpkg.com/cornerstone-core@2.3.0/dist/cornerstone.js"></script>
<script src="https://unpkg.com/cornerstone-math@0.1.9/dist/cornerstoneMath.min.js"></script>
<script src="https://unpkg.com/cornerstone-wado-image-loader@3.3.1/dist/cornerstoneWADOImageLoader.min.js"></script>
<script src="https://unpkg.com/cornerstone-web-image-loader@2.1.1/dist/cornerstoneWebImageLoader.min.js"></script>
<script src="https://unpkg.com/cornerstone-tools@5.1.4/dist/cornerstoneTools.js"></script>
<script src="https://unpkg.com/dicom-parser@1.8.7/dist/dicomParser.min.js"></script>

初始化内容

cornerstoneTools.external.cornerstone = cornerstone;
cornerstoneTools.external.Hammer = Hammer;
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;

cornerstoneTools.init();

const $ = name => document.querySelector(name);

const dicomImage = $("#dicomImage");
const H = document.documentElement.clientHeight - 100;
const W = document.documentElement.clientWidth / 2;
const toolState = {};
dicomImage.style.width = W + "px";
dicomImage.style.height = H + "px";
let imageId = "wadouri:http://127.0.0.1/download/1.dcm";
cornerstone.enable(dicomImage);
cornerstone.loadAndCacheImage(imageId).then(img => {
    cornerstone.displayImage(dicomImage, img);
});

let activeToolName = ""; // 激活工具名称
let prevToolName = ""; // 上一个激活工具名称

处理激活工具

$(".tools").onclick = function(e){
    const target = e.target;
    const tool = target.dataset.tool;
    if(target.nodeName != "BUTTON" && !tool)return;
    if(prevToolName){
            cornerstoneTools.setToolPassive(prevToolName); // 把上一个激活工具冻结
    }
    activeToolName = tool + "Tool";
    if(!toolState[activeToolName]){
            // 不能重复 addTool
            cornerstoneTools.addTool(cornerstoneTools[activeToolName], tool === "TextMarker" ? marker() : {});
            toolState[activeToolName] = true;
    }
    prevToolName = tool;
    // 激活工具
    cornerstoneTools.setToolActive(tool, {
        mouseButtonMask: 1
    });
}
// 标注工具要有初始配置
function marker(){
    return {
            configuration: {
            markers: ["F5", "F4", "F3", "F2", "F1"], //标记数组
            current: 'F3', //要对应markers
            loop: true, //是否循环
            ascending: false, //true 降序 false 升序
            changeTextCallback: function(data, eventData, doneChangingTextCallback) {
                data.visible = true; //是否可见, 默认true
                data.color = "#38f"; //文字颜色
                data.text = "内容"; //修改内容  这里修改了也没有,因为默认使用第二个参数
                doneChangingTextCallback(data, prompt('改变标注:'));
            }
        }
    }
}

监听测量添加

dicomImage.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_ADDED, e=>{
    // toolName 是当前使用的工具
    activeToolName = e.detail.toolName + "Tool"
})

监听测量完成

dicomImage.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_COMPLETED,e=>{
    console.log("绘制完成: ", activeToolName)
    activeToolName = "";
})

监听鼠标抬起

dicomImage.addEventListener(cornerstoneTools.EVENTS.MOUSE_UP,e=>{
    const detail = e.detail;
    if(activeToolName || !prevToolName || detail.event.button != 2)return;
    const imageId = detail.image.imageId; // 获取imageId
    const viewport = detail.viewport; // 获取viewport属性
    // 通过元素获取工具状态,状态在通过imageId获取使用过的工具,就是在这张图片上显示的绘制内容
    const tools = cornerstoneTools.getElementToolStateManager(dicomImage).toolState[imageId];
    for(let item of Object.keys(tools)){ // 遍历key值
        const data = tools[item].data; // 通过key 拿到每个工具绘制的数据,多个绘制就会有多条数据
        for(let i = 0, len = data.length; i < len; i++){
            const tool = data[i];
            if(tool.active){ // 如果工具激活,那么就为true,激活状态就是绘制内容高亮显示
                $(".imgId").innerText = imageId;
                $(".draw-data").innerText = JSON.stringify(tool);
                $(".tool").innerText = item;
                $(".wc").innerText = viewport.voi.windowCenter;
                $(".ww").innerText = viewport.voi.windowWidth;
                $(".rotate").innerText = viewport.rotation;
                $(".scale").innerText = viewport.scale;
                $(".translate").innerText = `x : ${viewport.translation.x},y : ${viewport.translation.y}`;
                $(".vflip").innerText = viewport.vflip;
                $(".hflip").innerText = viewport.hflip;
                $(".invert").innerText = viewport.invert;
                $(".voi").innerText = JSON.stringify(viewport.voi)
                return
            }
        }
    }
})

上述是使用 cornerstoneTools的事件获取信息,鼠标要在200毫秒后才能抬起,否则是不会触发事件。
也可以使用鼠标移动的方式,这个就要考虑防抖或节流了。
直接在元素身上用mousedown也可,只是没有 e.detail属性,要自己获取当前的图像。

使用 mousedown 获取

dicomImage.addEventListener("mousedown",e=>{
    if(e.button != 2 || activeToolName || !prevToolName)return;
    const img = cornerstone.getImage(dicomImage); // 获取当前激活图像
    const viewport = cornerstone.getViewport(dicomImage); // 获取当前图像 viewport
    const tools = cornerstoneTools.getElementToolStateManager(dicomImage).toolState[img.imageId];
    for(let item of Object.keys(tools)){
    const data = tools[item].data;
    for(let i = 0, len = data.length; i < len; i++){
        const tool = data[i];
        if(tool.active){
            $(".imgId").innerText = img.imageId;
            $(".draw-data").innerText = JSON.stringify(tool);
            $(".tool").innerText = item;
            $(".wc").innerText = viewport.voi.windowCenter;
            $(".ww").innerText = viewport.voi.windowWidth;
            $(".rotate").innerText = viewport.rotation;
            $(".scale").innerText = viewport.scale;
            $(".translate").innerText = `x : ${viewport.translation.x},y : ${viewport.translation.y}`;
            $(".vflip").innerText = viewport.vflip;
            $(".hflip").innerText = viewport.hflip;
            $(".invert").innerText = viewport.invert;
            $(".voi").innerText = JSON.stringify(viewport.voi)
            return
        }
    }
}
})

这是两种方案能获取工具信息。