cornerstonejs Demo 示例

cornerstone学习日记

一、这是由javascript驱动的最小使用基石的示例


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        jsminimal/index.html
    </h1>

    This is an example of the minimal use of cornerstone driven by javascript

    <br>
    <br>

    In this example, javascript is used to image enable a div.

    <br>
    <br>

    <div id="dicomImage" style="width:512px;height:512px">
    </div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    const imageId = 'example://1';
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);
    });
</script>
</html>

二、本示例演示了在首次使图像聚焦于图像中的肿瘤时设置各种视口设置。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        viewport/index.html
    </h1>

    This example demonstrates setting various viewport settings when the image is first enabled to
    focus on a tumor in the image.

    <br>
    <br>

    <div id="dicomImage" style="width:512px;height:512px;"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    const viewportOptions = {
        scale: 6.0,
        translation: {
            x: -24,
            y: 10
        },
        voi: {
            windowWidth: 89,
            windowCenter: 150
        },
        invert: false,
        pixelReplication: false
    };
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);
    cornerstone.loadImage("example://1").then(function (image) {
        cornerstone.displayImage(element, image, viewportOptions);
    });
</script>
</html>

三、这是调整已启用图像大小的示例。

当启用的元素的宽度或高度发生变化时,必须调用resize()以便基石可以更新画布的宽度和高度。图像将自动缩放。当图像在调整大小之前适合窗口时,在调整大小之后也将适合窗口。如果在调整大小之前缩放或平移了图像,则图像将进行相应缩放。通过拖动图像右上角的红色方块在此处尝试此操作。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        resize/index.html
    </h1>

    This is an example of resizing the enabled image

    <br>

    When the enabled element's width or height changes, you must call resize() so cornerstone can update
    the canvas width and height. The image is automatically rescaled. When the image fitted the window
    before the resize then it will also fit after the resize. If the image was zoomed or panned before
    the resize then the image will be rescaled accordingly. Try this out here by dragging the red square
    in the right corner of the image.

    <br>
    <br>
    <label>Row Pixel Spacing:</label>
    <input id="rowPixelSpacing" type="text" value="" />
    <span>&#32;</span>
    <label>Column Pixel Spacing:</label>
    <input id="colPixelSpacing" type="text" value="" />
    <br>
    <br>
    <button id="reset" class="btn">Reset & fit to window</button>
    <button id="randomZoomPan" class="btn">Apply random zoom & pan</button>

    <br>
    <br>

    <div style="display:inline-block;position:relative">
      <div
        id="resizeKnob"
        style="position:absolute;right:-5px;bottom:-5px;width:20px;height:20px;background:red;cursor:se-resize">
      </div>
      <div id="dicomImage" style="width:256px;height:256px"
           oncontextmenu="return false"
           onmousedown="return false">
      </div>
    </div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    // image enable the dicomImage element
    const imageId = 'example://1';
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);

        document.getElementById('rowPixelSpacing').value = image.rowPixelSpacing;
        document.getElementById('colPixelSpacing').value = image.columnPixelSpacing;
    });

    function doResize(width, height) {
        if (width < 100)
            width = 100
        if (height < 100)
            height = 100

        element.style.width = width + 'px';
        element.style.height = height + 'px';
        cornerstone.resize(element);
    }

    function getRandomFloat(min, max) {
        return Math.random() * (max - min) + min;
    }

    document.getElementById('resizeKnob').addEventListener('mousedown', function (e) {
        const initWidth = element.clientWidth;
        const initHeight = element.clientHeight;
        const startX = e.clientX;
        const startY = e.clientY;
        function dragResize (e) {
            const x = e.clientX - startX;
            const y = e.clientY - startY;
            const w = initWidth + x;
            const h = initHeight + y;
            doResize(w, h);
        }
        document.addEventListener('mousemove', dragResize);
        document.addEventListener('mouseup', function (e) {
            document.removeEventListener('mouseup', arguments.callee);
            document.removeEventListener('mousemove', dragResize);
        })
    });

    document.getElementById('reset').addEventListener('click', function (e) {
        let image = cornerstone.getImage(element);

        element.style.width = '256px';
        element.style.height = '256px';

        image.rowPixelSpacing = parseInt (document.getElementById('rowPixelSpacing').value, 10);
        image.columnPixelSpacing = parseInt(document.getElementById('colPixelSpacing').value, 10);

        cornerstone.resize(element, true);
    });

    document.getElementById('randomZoomPan').addEventListener('click', function (e) {
        let viewport = cornerstone.getViewport(element);
        let image = cornerstone.getImage(element);
        const scale = viewport.scale;
        const minScale = scale - scale / 2;
        const maxScale = scale + scale / 2;
        viewport.scale = getRandomFloat(minScale, maxScale);
        viewport.translation.x = getRandomFloat(-50.0, 50.0)
        viewport.translation.y = getRandomFloat(-50.0, 50.0)



        image.rowPixelSpacing = parseInt(document.getElementById('rowPixelSpacing').value, 10);
        image.columnPixelSpacing = parseInt(document.getElementById('colPixelSpacing').value, 10);

        cornerstone.setViewport(element, viewport);
    });

</script>
</html>

四、这是更改元素中显示的图像的示例。这可用于显示不同的关键图像或一堆图像(例如MRI系列)。使用鼠标滚轮在图像之间切换或按下面的按钮。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">

        <h1>
            changeimage/index.html
        </h1>

        This is an example of changing the image displayed in an element.  This could be used
        to show different key images or a stack of images (e.g. MRI series).  Use the mouse wheel
        to change between images or press the buttons below.

        <br>
        <br>

        <div id="dicomImage" style="width:512px;height:512px"
            oncontextmenu="return false"
            onmousedown="return false">
        </div>

        <button id="imageButton1" type="button" class="btn btn-default">Image #1</button>
        <button id="imageButton2" type="button" class="btn btn-default">Image #2</button>

    </div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    const imageIds = [
        'example://1',
        'example://2'
    ];

    let currentImageIndex = 0;

    // show image #1 initially
    function updateTheImage(imageIndex) {
        currentImageIndex = imageIndex;
        cornerstone.loadImage(imageIds[currentImageIndex]).then(function(image) {
            cornerstone.displayImage(element, image);
        });
    }

    updateTheImage(0);

    // Add event handlers to change images
    document.getElementById('imageButton1').addEventListener('click', function (e) {
        updateTheImage(0);
    });

    document.getElementById('imageButton2').addEventListener('click', function (e) {
        updateTheImage(1);
    });

    const wheelEvents = ['mousewheel', 'DOMMouseScroll'];

    wheelEvents.forEach((eventType) => {
      element.addEventListener(eventType, function (e) {
        // 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) {
          if (currentImageIndex === 0) {
            updateTheImage(1);
          }
        } else {
          if (currentImageIndex === 1) {
            updateTheImage(0);
          }
        }

        // Prevent page fom scrolling
        return false;
      });
    });
</script>
</html>

五、是交互式窗口/级别的示例

在此示例中,鼠标移动被捕获并调整窗宽/窗位。您也可以通过在输入元素中输入值并单击“应用”来手动设置窗宽/窗位。按下反转按钮以切换图像的反转。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        windowlevel/index.html
    </h1>

    This is an example of interactive window/level

    <br>
    <br>

    In this example, the mousemove is captured and adjusts the window/center.  You can also manually set the window/center
    by entering the values in the input elements and hitting apply.  Press the Invert button to toggle invert
    for the image.

    <br>
    <br>

    <div id="dicomImage" style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

    <br>

    <label>Window Width</label>
    <input id="ww" type="text" placeholder="e.g. 1000" value="256">
    <label>Window Center</label>
    <input id="wc" type="text" placeholder="e.g. 500" value="128">
    <button id="apply" class="btn">Apply</button>
    <button id="invert" class="btn">Invert</button>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // load the image and display it
    const imageId = 'example://1';
    cornerstone.loadImage(imageId).then(function(image) {
       cornerstone.displayImage(element, image);
    });

    // Add event handler to the ww/wc apply button
    document.getElementById('apply').addEventListener('click', function (e) {
        let viewport = cornerstone.getViewport(element);
        viewport.voi.windowWidth = parseFloat(document.getElementById('ww').value);
        viewport.voi.windowCenter = parseFloat(document.getElementById('wc').value);
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('invert').addEventListener('click', function (e) {
        let viewport = cornerstone.getViewport(element);
        viewport.invert = !viewport.invert;
        cornerstone.setViewport(element, viewport);
    });

    // add event handlers to mouse move to adjust window/center
    element.addEventListener('mousedown', function (e) {
        let lastX = e.pageX;
        let lastY = e.pageY;

        function mouseMoveHandler(e) {
            const deltaX = e.pageX - lastX;
            const deltaY = e.pageY - lastY;
            lastX = e.pageX;
            lastY = e.pageY;

            let viewport = cornerstone.getViewport(element);
            viewport.voi.windowWidth += (deltaX / viewport.scale);
            viewport.voi.windowCenter += (deltaY / viewport.scale);
            cornerstone.setViewport(element, viewport);
        };

        function mouseUpHandler() {
            document.removeEventListener('mousemove', mouseMoveHandler);
            document.removeEventListener('mouseup', mouseUpHandler);
        }

        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
    });
</script>
</html>

六、这是交互式缩放和平移的示例。
在此示例中,可以通过鼠标滚轮或屏幕上的按钮更改缩放比例。通过鼠标左键拖动来完成平移。请注意,核心基石库未指定任何交互范例,并且允许开发人员实现任何交互范例


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        zoompan/index.html
    </h1>

    This is an example of interactive zoom and pan.

    <br>

    In this example, the zoom can be changed via the mouse wheel or the buttons on the screen.
    Panning is done via left mouse click dragging.  Note that the core cornerstone library does
    not specify any interaction paradigm and allows any interaction paradigm to be implemented
    by the developer

    <br>
    <br>

    <div id="dicomImage"
         style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

    <br>

    <button id="zoomIn" type="button" class="btn btn-default">Zoom In</button>
    <button id="zoomOut" type="button" class="btn btn-default">Zoom Out</button>
    <button id="reset" type="button" class="btn btn-default">Reset</button>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    // image enable the dicomImage element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    //load the image and display it
    const imageId = 'example://1';
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);
    });

    // Add event handlers to zoom the image in and out
    document.getElementById('zoomIn').addEventListener('click', function (e) {
        const viewport = cornerstone.getViewport(element);
        viewport.scale += 0.25;
        cornerstone.setViewport(element, viewport);
    });
    document.getElementById('zoomOut').addEventListener('click', function (e) {
        const viewport = cornerstone.getViewport(element);
        viewport.scale -= 0.25;
        cornerstone.setViewport(element, viewport);
    });
    document.getElementById('reset').addEventListener('click', function (e) {
        cornerstone.reset(element);
    });

    // add event handlers to pan image on mouse move
    element.addEventListener('mousedown', function (e) {
      let lastX = e.pageX;
      let lastY = e.pageY;

      function mouseMoveHandler(e) {
        const deltaX = e.pageX - lastX;
        const deltaY = e.pageY - lastY;
        lastX = e.pageX;
        lastY = e.pageY;

        const viewport = cornerstone.getViewport(element);
        viewport.translation.x += (deltaX / viewport.scale);
        viewport.translation.y += (deltaY / viewport.scale);
        cornerstone.setViewport(element, viewport);
      }

      function mouseUpHandler() {
        document.removeEventListener('mousemove', mouseMoveHandler);
        document.removeEventListener('mouseup', mouseUpHandler);
      }

      document.addEventListener('mousemove', mouseMoveHandler);
      document.addEventListener('mouseup', mouseUpHandler);
    });

    const mouseWheelEvents = ['mousewheel', 'DOMMouseScroll'];
    mouseWheelEvents.forEach(function(eventType) {
      element.addEventListener(eventType, function (e) {
        // Firefox e.detail > 0 scroll back, < 0 scroll forward
        // chrome/safari e.wheelDelta < 0 scroll back, > 0 scroll forward
        let viewport = cornerstone.getViewport(element);
        if (e.wheelDelta < 0 || e.detail > 0) {
          viewport.scale -= 0.25;
        } else {
          viewport.scale += 0.25;
        }

        cornerstone.setViewport(element, viewport);

        // Prevent page from scrolling
        return false;
      });
    });
</script>
</html>

七、这是打开/关闭插值的示例(显示像素)


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        interpolation/index.html
    </h1>

    This is an example of turning on/off interpolation

    <br>
    <br>

    <div id="dicomImage" style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

    <button id="interpolation" class="btn">Toggle Interpolation</button>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    // image enable the dicomImage element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // load the image and display it
    const imageId = 'example://1';
    cornerstone.loadImage(imageId).then(function(image) {
        const viewportOptions = {
            scale: 6.0
        };
        cornerstone.displayImage(element, image, viewportOptions);
    });

    document.getElementById('interpolation').addEventListener('click', function (e) {
        let viewport = cornerstone.getViewport(element);
        viewport.pixelReplication = !viewport.pixelReplication;
        cornerstone.setViewport(element, viewport);
    });

    // add event handlers to mouse move to adjust window/center
    element.addEventListener('mousedown', function (e) {
        let lastX = e.pageX;
        let lastY = e.pageY;

        function mouseMoveHandler(e) {
          const deltaX = e.pageX - lastX;
          const deltaY = e.pageY - lastY;
          lastX = e.pageX;
          lastY = e.pageY;

          let viewport = cornerstone.getViewport(element);
          viewport.voi.windowWidth += (deltaX / viewport.scale);
          viewport.voi.windowCenter += (deltaY / viewport.scale);
          cornerstone.setViewport(element, viewport);
        }

        function mouseUpHandler() {
          document.removeEventListener('mousemove', mouseMoveHandler);
          document.removeEventListener('mouseup', mouseUpHandler);
        }

        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
    });
</script>
</html>

八、此示例演示了如何使用HTML将叠加层放置在图像顶部


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">

    <style>
        .overlay {
            /* prevent text selection on overlay */
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;

            /* ignore pointer event on overlay */
            pointer-events: none;
        }
    </style>
</head>
<body>
<div class="container">

    <h1>
        htmloverlays/index.html
    </h1>

    This example demonstrates using HTML to put overlays on top of the image

    <br>
    <br>

    <!-- note we disable selection on the top most div -->
    <div style="width:512px;height:512px;position:relative;color:white"
         oncontextmenu="return false"
         onmousedown="return false">

        <div id="dicomImage"
             style="width:512px;height:512px;top:0px;left:0px;position:absolute">
        </div>

        <div id="topleft" class="overlay" style="position:absolute;top:0px;left:0px">
            Patient Name
        </div>
        <div id="topright" class="overlay" style="position:absolute;top:0px;right:0px">
            Hospital
        </div>
        <div id="bottomright" class="overlay" style="position:absolute;bottom:0px;right:0px">
            Zoom:
        </div>
        <div id="bottomleft" class="overlay" style="position:absolute;bottom:0px;left:0px">
            WW/WC:
        </div>
    </div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // load the image and display it
    const imageId = 'example://1';
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);
        const viewport = cornerstone.getViewport(element);
        document.getElementById('bottomright').textContent = "Zoom: " + viewport.scale + "x";
        document.getElementById('bottomleft').textContent = "WW/WC:" + Math.round(viewport.voi.windowWidth)
            + "/" + Math.round(viewport.voi.windowCenter);
    });

    // add event handlers to mouse move to adjust window/center
    element.addEventListener('mousedown', function (e) {
        let lastX = e.pageX;
        let lastY = e.pageY;

        function mouseMoveHandler(e) {
            const deltaX = e.pageX - lastX;
            const deltaY = e.pageY - lastY;
            lastX = e.pageX;
            lastY = e.pageY;

            let viewport = cornerstone.getViewport(element);
            viewport.voi.windowWidth += (deltaX / viewport.scale);
            viewport.voi.windowCenter += (deltaY / viewport.scale);
            cornerstone.setViewport(element, viewport);

            document.getElementById('bottomleft').textContent = "WW/WC:" + Math.round(viewport.voi.windowWidth)
                + "/" + Math.round(viewport.voi.windowCenter);
        }

        function mouseUpHandler() {
            document.removeEventListener('mousemove', mouseMoveHandler);
            document.removeEventListener('mouseup', mouseUpHandler);
        }

        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
    });
</script>
</html>

九、这是事件处理的示例。每当图像更新时,Cornerstone都会触发事件“ CornerstoneImageRendered”。该事件包括设置为图像坐标系的画布上下文,因此您可以绘制叠加层。每次加载图像时,基石也会在基石对象上触发事件“ cornerstoneImageLoaded”。
本示例通过使用更新的WW / WC值更新左下方的叠加层来说明这一点。它还通过在肿瘤周围绘制一个矩形并将其标记为“此处肿瘤”来说明图像本身的叠加。它还会更改文本“ Last ImageId Loaded:”以显示已加载的图像ID


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">

    <style>
        .overlay {
            /* prevent text selection on overlay */
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;

            /* ignore pointer event on overlay */
            pointer-events: none;
        }
    </style>
</head>
<body>
<div class="container">

    <h1>
        eventhandling/index.html
    </h1>

    This is an example of event handling.  Cornerstone fires the event 'CornerstoneImageRendered'
    everytime the image is updated.  The event includes the canvas context set to the image coordinate system
    so you can draw overlays.  Cornerstone also fires the event 'cornerstoneImageLoaded' on the cornerstone
    object every time an image is loaded.

    <br>

    This example illustrates this by updating the bottom left overlay with the updated WW/WC values.  It also
    illustrates overlays on the image itself by drawing a rectangle around a tumor and labeling it with the text
    "Tumor Here".  It also changes the text "Last ImageId Loaded:" to show the image id loaded

    <br>
    <br>

    <div id="imageLoaded">Last ImageId Loaded:</div>
    <div style="width:512px;height:512px;position:relative;color:white;"
         oncontextmenu="return false"
         onmousedown="return false">

        <div id="dicomImage"
             style="width:512px;height:512px;top:0px;left:0px;position:absolute">
        </div>

        <div id="topleft" class="overlay" style="position:absolute;top:0px;left:0px">
            Patient Name
        </div>
        <div id="topright" class="overlay" style="position:absolute;top:0px;right:0px">
            Render Time:
        </div>
        <div id="bottomright" class="overlay" style="position:absolute;bottom:0px;right:0px">
            Zoom:
        </div>
        <div id="bottomleft" class="overlay" style="position:absolute;bottom:0px;left:0px">
            WW/WC:
        </div>
    </div>
</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // setup handlers before we display the image
    function onImageRendered(e) {
        const eventData = e.detail;

        // set the canvas context to the image coordinate system
        cornerstone.setToPixelCoordinateSystem(eventData.enabledElement, eventData.canvasContext);

        // NOTE: The coordinate system of the canvas is in image pixel space.  Drawing
        // to location 0,0 will be the top left of the image and rows,columns is the bottom
        // right.
        const context = eventData.canvasContext;
        context.beginPath();
        context.strokeStyle = 'white';
        context.lineWidth = .5;
        context.rect(128, 90, 50, 60);
        context.stroke();
        context.fillStyle = "white";
        context.font = "6px Arial";
        context.fillText("Tumor Here", 128, 85);

        context.beginPath();
        context.arc(128, 128, 20, 0, 2 * Math.PI, false);
        context.fillStyle = 'green';
        context.lineWidth = -1;
        context.strokeStyle = 'white';
        context.stroke();

        document.getElementById('topright').textContent = "Render Time:" + eventData.renderTimeInMs + " ms";
        document.getElementById('bottomleft').textContent = "WW/WL:" + Math.round(eventData.viewport.voi.windowWidth) + "/" + Math.round(eventData.viewport.voi.windowCenter);
        document.getElementById('bottomright').textContent = "Zoom:" + eventData.viewport.scale.toFixed(2);

    }
    element.addEventListener('cornerstoneimagerendered', onImageRendered);

    cornerstone.events.addEventListener('cornerstoneimageloaded', function(e) {
        const eventData = e.detail;
        document.getElementById('imageLoaded').textContent = `Last ImageId Loaded: ${eventData.image.imageId}`;
    });

    // load the image and display it
    const imageId = 'example://1';
    cornerstone.loadImage(imageId).then(function (image) {
        // Now set the image which will fire the events we are interested in
        cornerstone.displayImage(element, image);

        // add event handlers to pan image on mouse move
        element.addEventListener('mousedown', function (e) {
            let lastX = e.pageX;
            let lastY = e.pageY;
            const mouseButton = e.which;

            function mouseMoveHandler(e) {
                const deltaX = e.pageX - lastX;
                const deltaY = e.pageY - lastY;
                lastX = e.pageX;
                lastY = e.pageY;

                if (mouseButton === 1) {
                    let viewport = cornerstone.getViewport(element);
                    viewport.voi.windowWidth += (deltaX / viewport.scale);
                    viewport.voi.windowCenter += (deltaY / viewport.scale);
                    cornerstone.setViewport(element, viewport);
                } else if (mouseButton === 2) {
                    let viewport = cornerstone.getViewport(element);
                    viewport.translation.x += (deltaX / viewport.scale);
                    viewport.translation.y += (deltaY / viewport.scale);
                    cornerstone.setViewport(element, viewport);
                } else if (mouseButton === 3) {
                    let viewport = cornerstone.getViewport(element);
                    viewport.scale += (deltaY / 100);
                    cornerstone.setViewport(element, viewport);
                }
            }

            function mouseUpHandler() {
                document.removeEventListener('mousemove', mouseMoveHandler);
                document.removeEventListener('mouseup', mouseUpHandler);
            }

            document.addEventListener('mousemove', mouseMoveHandler);
            document.addEventListener('mouseup', mouseUpHandler);
        });
    });
</script>
</html>

十、此示例显示了一个非常简单的ImageLoader,它可以动态生成图像。真正的图像加载器当然会从服务器获取数据。注意-其他实时示例使用自定义ImageLoader,该图像加载器具有以base64编码的字符串形式存储在其中的图像像素数据。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        imageloader/index.html
    </h1>

    This example shows a very simple ImageLoader which generates the image on the fly.  A real image loader
    would of course get the data form a server.  Note - the other live examples use a custom ImageLoader
    which have the pixel data for images stored in them as base64 encoded strings.

    <br>
    <br>

    <div id="dicomImage" style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<script>
    // Loads an image given an imageId
    function loadImage(imageId) {
        const width = 256;
        const height = 256;
        const numPixels = width * height;
        const pixelData = new Uint16Array(numPixels);
        const rnd = Math.round(Math.random() * 255);
        let index = 0;
        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                pixelData[index] = (x + rnd) % 256;
                index++;
            }
        }

        function getPixelData() {
            return pixelData;
        }

        const image = {
            imageId: imageId,
            minPixelValue: 0,
            maxPixelValue: 255,
            slope: 1.0,
            intercept: 0,
            windowCenter: 127,
            windowWidth: 256,
            render: cornerstone.renderGrayscaleImage,
            getPixelData: getPixelData,
            rows: height,
            columns: width,
            height: height,
            width: width,
            color: false,
            columnPixelSpacing: 1.0,
            rowPixelSpacing: 1.0,
            invert: false,
            sizeInBytes: width * height * 2
        };

        return {
          promise: new Promise((resolve) => resolve(image)),
          cancelFn: undefined
        }
    }

    cornerstone.registerImageLoader('myImageLoader', loadImage);

    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // load the image and display it
    const imageId = 'myImageLoader://1';
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);
    });
</script>
</html>

十一、这是在一页上显示两个mr图像和一个ct图像的示例。请注意,在这种情况下,使用了两个不同的imageId插件-一个用于mr图像,一个用于ct图像。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        multimage/index.html
    </h1>

    This is an example of showing two mr images and one ct image on one page.  Note that two different
    imageId plugins are used in this case - one for the mr images and one for the ct image.

    <br>
    <br>

    <div id="mr1" style="width:256px;height:256px;display:inline-block"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>
    <div id="mr2" style="width:256px;height:256px;display:inline-block"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>
    <div id="ct1" style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoaderCt.js"></script>

<script>
    // image enable the elements
    const mr1 = document.getElementById('mr1');
    cornerstone.enable(mr1);

    const mr2 = document.getElementById('mr2');
    cornerstone.enable(mr2);

    const ct1 = document.getElementById('ct1');
    cornerstone.enable(ct1);

    // load and display the images
    cornerstone.loadAndCacheImage('example://1').then(function(image) {
        cornerstone.displayImage(mr1, image);
    });
    cornerstone.loadAndCacheImage('example://2').then(function(image) {
        cornerstone.displayImage(mr2, image);
    });
    cornerstone.loadAndCacheImage('ctexample://1').then(function(image) {
        cornerstone.displayImage(ct1, image);
    });
</script>
</html>

十二、这是显示ct图像以及用于设置ww / wc预设的按钮的示例。您可以通过拖动鼠标左键来手动调整ww / wc


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        ctimage/index.html
    </h1>

    This is an example of displaying a ct image along with buttons to set ww/wc presets.  You can
    manually adjust the ww/wc by dragging the left mouse button

    <br>
    <br>

    <div id="dicomImage"
        style="width:512px;height:512px"
        oncontextmenu="return false"
        onmousedown="return false">
    </div>

    <br>

    <button id="softTissue" class="btn">Soft Tissue</button>
    <button id="lung" class="btn">Lung</button>
    <button id="bone" class="btn">Bone</button>
    <span id="window">WW/WC:</span>
</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoaderCt.js"></script>

<script>
    // image enable the dicomImage element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // load and display the image
    const imageId = 'ctexample://1';
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);

        const viewport = cornerstone.getViewport(element);
        document.getElementById('window').textContent = "WW/WC:" + Math.round(viewport.voi.windowWidth)
            + "/" + Math.round(viewport.voi.windowCenter);

        // Add event handler for the ww/wc presets
        document.getElementById('softTissue').addEventListener('click', function() {
            let viewport = cornerstone.getViewport(element);
            viewport.voi.windowWidth = 400;
            viewport.voi.windowCenter = 20;
            cornerstone.setViewport(element, viewport);
            document.getElementById('window').textContent = "WW/WC:" + Math.round(viewport.voi.windowWidth)
                + "/" + Math.round(viewport.voi.windowCenter);
        });

        document.getElementById('lung').addEventListener('click', function() {
            let viewport = cornerstone.getViewport(element);
            viewport.voi.windowWidth = 1600;
            viewport.voi.windowCenter = -600;
            cornerstone.setViewport(element, viewport);
            document.getElementById('window').textContent = "WW/WC:" + Math.round(viewport.voi.windowWidth)
                + "/" + Math.round(viewport.voi.windowCenter);
        });

        document.getElementById('bone').addEventListener('click', function() {
            let viewport = cornerstone.getViewport(element);
            viewport.voi.windowWidth = 2000;
            viewport.voi.windowCenter = 300;
            cornerstone.setViewport(element, viewport);
            document.getElementById('window').textContent = "WW/WC:" + Math.round(viewport.voi.windowWidth)
                + "/" + Math.round(viewport.voi.windowCenter);
        });


        // add event handlers to mouse move to adjust window/center
        element.addEventListener('mousedown', function (e) {
            let lastX = e.pageX;
            let lastY = e.pageY;

            function mouseMoveHandler(e) {
                const deltaX = e.pageX - lastX;
                const deltaY = e.pageY - lastY;
                lastX = e.pageX;
                lastY = e.pageY;

                let viewport = cornerstone.getViewport(element);
                viewport.voi.windowWidth += (deltaX / viewport.scale);
                viewport.voi.windowCenter += (deltaY / viewport.scale);
                cornerstone.setViewport(element, viewport);
                document.getElementById('window').textContent = "WW/WC:" + Math.round(viewport.voi.windowWidth)
                    + "/" + Math.round(viewport.voi.windowCenter);
            }

            function mouseUpHandler() {
                document.removeEventListener('mousemove', mouseMoveHandler);
                document.removeEventListener('mouseup', mouseUpHandler);
            }

            document.addEventListener('mousemove', mouseMoveHandler);
            document.addEventListener('mouseup', mouseUpHandler);
        });
    });
</script>
</html>

十三、本示例显示具有非正方形像素的图像。图像为128x256,列和行像素间距分别为1.0 / 0.5。如果正确应用了非正方形像素,则图像将显示正方形,否则将显示高矩形。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        nonSquarePixels/index.html
    </h1>

    This example shows an image with non square pixels.  The image is 128x256 and has a column and row pixel spacing
    of 1.0/0.5 respectively.  The image will display a square if non square pixels is being applied properly
    or a tall rectangle if not.

    <br>
    <br>

    <button id="hFlip" type="button" class="btn btn-default">HFlip</button>
    <button id="vFlip" type="button" class="btn btn-default">VFlip</button>
    <button id="lRotate" type="button" class="btn btn-default">Rotate Left</button>
    <button id="rRotate" type="button" class="btn btn-default">Rotate Right</button>
    <button id="reset" type="button" class="btn btn-default">Reset</button>

    <br>
    <br>

    <div id="dicomImage" style="width:256px;height:256px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

    <div><span id="coords"></span></div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<script>
    // Loads an image given an imageId
    function loadImage(imageId) {

        var width = 128;
        var height = 256;

        var numPixels = width * height;
        var pixelData = new Uint16Array(numPixels);
        var index = 0;
        // clear image to black
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                pixelData[index] = 128;
                index++;
            }
        }

        var left = 10;
        var top = 20;
        var squareWidth = 50;
        var squareHeight = 100;

        for (var row = top; row < top + squareHeight; row++) {
            var rowOffset = row * width;
            pixelData[rowOffset + left] = 255;
            pixelData[rowOffset + left + squareWidth] = 255;
        }
        var topRowOffset = top * width;
        var bottomRowOffset = (top + squareHeight) * width;
        for (var column = left; column < left + squareWidth; column++) {
            pixelData[topRowOffset + column] = 255;
            pixelData[bottomRowOffset + column] = 255;
        }

        function getPixelData()
        {
            return pixelData;
        }

        var image = {
            imageId: imageId,
            minPixelValue: 0,
            maxPixelValue: 255,
            slope: 1.0,
            intercept: 0,
            windowCenter: 127,
            windowWidth: 256,
            render: cornerstone.renderGrayscaleImage,
            getPixelData: getPixelData,
            rows: height,
            columns: width,
            height: height,
            width: width,
            color: false,
            columnPixelSpacing: 1.0,
            rowPixelSpacing: 0.5,
            invert: false,
            sizeInBytes: width * height * 2
        };

        // Create a Promise, resolve it with the image object we just created and return the
        // Promise to cornerstone.  Cornerstone will get the image object by calling then() on the
        // Promise. An optional function can be provided to allow the image loader to cancel a request.
        return {
          promise: new Promise((resolve) => {
            resolve(image);
          }),
          cancelFn: undefined
        };
    }

    cornerstone.registerImageLoader('myImageLoader', loadImage);

    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // load and display the image
    const imageId = "myImageLoader://1";
    cornerstone.loadImage(imageId).then(function(image) {

        element.addEventListener("cornerstoneimagerendered", function(e) {
            const eventData = e.detail;

            // reset to identity matrix
            eventData.canvasContext.setTransform(1, 0, 0, 1, 0, 0);

            var context = eventData.canvasContext;
            context.beginPath();
            context.strokeStyle = 'white';
            context.lineWidth = 0;
            var topLeft = cornerstone.pixelToCanvas(element, {x:30, y:30});
            var bottomRight = cornerstone.pixelToCanvas(element, {x:40, y:40});

            context.rect(topLeft.x, topLeft.y, bottomRight.x-topLeft.x, bottomRight.y - topLeft.y);
            context.stroke();

            context.fillStyle = "white";
            context.font = "14px Arial";
            context.fillText("Tumor Here", topLeft.x, topLeft.y);
        });
        cornerstone.displayImage(element, image);
    });

    // Add event handlers to flip or rotate the image
    document.getElementById('hFlip').addEventListener('click', function (e) {
        var viewport = cornerstone.getViewport(element);
        viewport.hflip = !viewport.hflip;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('vFlip').addEventListener('click', function (e) {
        var viewport = cornerstone.getViewport(element);
        viewport.vflip = !viewport.vflip;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('lRotate').addEventListener('click', function (e) {
        var viewport = cornerstone.getViewport(element);
        viewport.rotation-=90;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('rRotate').addEventListener('click', function (e) {
        var viewport = cornerstone.getViewport(element);
        viewport.rotation+=90;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('reset').addEventListener('click', function (e) {
        cornerstone.reset(element);
    });

    element.addEventListener('mousemove', function(event) {
        const pixelCoords = cornerstone.pageToPixel(element, event.pageX, event.pageY);
        const pt = cornerstone.pixelToCanvas(element, pixelCoords);
        document.getElementById('coords').textContent = "page=(" + event.pageX + ", " + event.pageY + "); pixel=(" + pixelCoords.x.toFixed(1) + ", " + pixelCoords.y.toFixed(1) + '); canvas=(' + pt.x.toFixed(1) + ', ' + pt.y.toFixed(1) + ')';
    });

    // add event handlers to pan image on mouse move
    element.addEventListener('mousedown', function (e) {
      let lastX = e.pageX;
      let lastY = e.pageY;

      function mouseMoveHandler(e) {
        const deltaX = e.pageX - lastX;
        const deltaY = e.pageY - lastY;
        lastX = e.pageX;
        lastY = e.pageY;

        const viewport = cornerstone.getViewport(element);
        viewport.translation.x += (deltaX / viewport.scale);
        viewport.translation.y += (deltaY / viewport.scale);
        cornerstone.setViewport(element, viewport);
      }

      function mouseUpHandler() {
        document.removeEventListener('mousemove', mouseMoveHandler);
        document.removeEventListener('mouseup', mouseUpHandler);
      }

      document.addEventListener('mousemove', mouseMoveHandler);
      document.addEventListener('mouseup', mouseUpHandler);
    });

    const mouseWheelEvents = ['mousewheel', 'DOMMouseScroll'];
    mouseWheelEvents.forEach(function(eventType) {
      element.addEventListener(eventType, function (e) {
        // Firefox e.detail > 0 scroll back, < 0 scroll forward
        // chrome/safari e.wheelDelta < 0 scroll back, > 0 scroll forward
        let viewport = cornerstone.getViewport(element);
        if (e.wheelDelta < 0 || e.detail > 0) {
          viewport.scale -= 0.25;
        } else {
          viewport.scale += 0.25;
        }

        cornerstone.setViewport(element, viewport);

        // Prevent page from scrolling
        return false;
      });
    });
</script>
</html>

十四、此示例显示了基石如何显示彩色图像。它使用返回彩色图像的自定义图像加载器


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        colorImage/index.html
    </h1>
    This example shows how cornerstone can display color images.  It uses a custom image loader
    that returns a color image
    <br>
    <br>

    <div id="dicomImage"
         style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

    <br>

    <div id="renderTime" />

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<script>
    const canvas = document.createElement('canvas');

    // Loads an image given an imageId
    function loadImage(imageId) {
        const width = 256;
        const height = 256;

        canvas.width = width;
        canvas.height = height;
        const canvasContext = canvas.getContext('2d');
        const imageData = canvasContext.createImageData(width, height);
        const pixelData = imageData.data;
        const rnd = Math.round(Math.random() * 255);
        let index = 0;
        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                pixelData[index++] = (x + rnd) % 256; // RED
                pixelData[index++] = 0; // GREEN
                pixelData[index++] = 0; // BLUE
                pixelData[index++] = 255; // ALPHA
            }
        }
        canvasContext.putImageData(imageData, 0, 0);

        function getPixelData() {
            return pixelData;
        }

        function getImageData() {
            return imageData;
        }

        function getCanvas() {
            return canvas;
        }

        const image = {
            imageId: imageId,
            minPixelValue: 0,
            maxPixelValue: 255,
            slope: 1.0,
            intercept: 0,
            windowCenter: 128,
            windowWidth: 255,
            render: cornerstone.renderColorImage,
            getPixelData: getPixelData,
            getImageData: getImageData,
            getCanvas: getCanvas,
            rows: height,
            columns: width,
            height: height,
            width: width,
            color: true,
            columnPixelSpacing: 1.0,
            rowPixelSpacing: 1.0,
            invert: false,
            sizeInBytes : width * height * 4
        };


        return {
            promise: new Promise((resolve) => resolve(image)),
            cancelFn: undefined
        };
    }

    cornerstone.registerImageLoader('colorImageLoader', loadImage);

    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    function onImageRendered(e) {
        const eventData = e.detail;
        document.getElementById('renderTime').textContent = "Render Time:" + eventData.renderTimeInMs + " ms";
    }
    element.addEventListener('cornerstoneimagerendered', onImageRendered);

    // load image and display it
    const imageId = "colorImageLoader://1";
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);
    });

    // add event handlers to mouse move to adjust window/center
    element.addEventListener('mousedown', function (e) {
      let lastX = e.pageX;
      let lastY = e.pageY;

      function mouseMoveHandler(e) {
        const deltaX = e.pageX - lastX;
        const deltaY = e.pageY - lastY;
        lastX = e.pageX;
        lastY = e.pageY;

        let viewport = cornerstone.getViewport(element);
        viewport.voi.windowWidth += (deltaX / viewport.scale);
        viewport.voi.windowCenter += (deltaY / viewport.scale);
        cornerstone.setViewport(element, viewport);
      }

      function mouseUpHandler() {
        document.removeEventListener('mousemove', mouseMoveHandler);
        document.removeEventListener('mouseup', mouseUpHandler);
      }

      document.addEventListener('mousemove', mouseMoveHandler);
      document.addEventListener('mouseup', mouseUpHandler);
    });
</script>
</html>

十五、本示例说明图像缓存的工作方式


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        imageCache/index.html
    </h1>

    This example shows how the image cache works

    <br>
    <br>

    <button id="purge" class="btn">Purge Cache</button>
    <button id="addImage" class="btn">Add Image</button>
    <button id="changeImageSize" class="btn">Change Image Size</button>

    <br>
    <br>

    <div id="dicomImage"
         style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

    <br>

    <label>Maximum Cache Size</label>
    <input id="maxCacheSize" type="text" placeholder="">
    <label>Current Cache Size:</label>
    <input id="currentCacheSize" readonly type="text" placeholder="" value="">
    <label># Images Cached:</label>
    <input id="numImagesCached" readonly type="text" placeholder="" value="">
    <button id="apply" class="btn">Apply</button>

    <br>

    <div id="renderTime" />

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<script>
    const cacheInfo = cornerstone.imageCache.getCacheInfo();
    document.getElementById('maxCacheSize').value = cacheInfo.maximumSizeInBytes;
    document.getElementById('apply').addEventListener('click', function () {
        const maxSizeInBytes = parseFloat(document.getElementById('maxCacheSize').value);
        cornerstone.imageCache.setMaximumSizeBytes(maxSizeInBytes);
    });
    document.getElementById('purge').addEventListener('click', function () {
        cornerstone.imageCache.purgeCache();
        document.getElementById('currentCacheSize').value = cacheInfo.cacheSizeInBytes;
        document.getElementById('numImagesCached').value = cacheInfo.numberOfImagesCached;
    });

    let imageNum = 2;
    document.getElementById('addImage').addEventListener('click', function() {
        const imageId = "colorImageLoader://" + imageNum++;
        cornerstone.loadAndCacheImage(imageId).then(function(image) {
          const cacheInfo = cornerstone.imageCache.getCacheInfo();
          cornerstone.displayImage(element, image);
          document.getElementById('currentCacheSize').value = cacheInfo.cacheSizeInBytes;
          document.getElementById('numImagesCached').value = cacheInfo.numberOfImagesCached;
        });
    });

    document.getElementById('changeImageSize').addEventListener('click', function() {
        const imageId = "colorImageLoader://1";
        cornerstone.imageCache.changeImageIdCacheSize(imageId, 512 * 1024);
    });

    var canvas = document.createElement('canvas');

    // Loads an image given an imageId
    function loadImage  (imageId) {
        var width = 256;
        var height = 256;

        canvas.width = width;
        canvas.height = height;
        var canvasContext = canvas.getContext('2d');
        var imageData = canvasContext.createImageData(width, height);
        var pixelData = imageData.data;
        var index = 0;
        var rnd = Math.round(Math.random() * 255);
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                pixelData[index++] = (x + rnd) % 256; // RED
                pixelData[index++] = 0; // GREEN
                pixelData[index++] = 0; // BLUE
                pixelData[index++] = 255; // ALPHA
            }
        }
        canvasContext.putImageData(imageData, 0, 0);

        function getPixelData() {
            return pixelData;
        }

        function getImageData() {
            return imageData;
        }

        function getCanvas() {
            return canvas;
        }

        var image = {
            imageId: imageId,
            minPixelValue: 0,
            maxPixelValue: 255,
            slope: 1.0,
            intercept: 0,
            windowCenter: 127,
            windowWidth: 256,
            getPixelData: getPixelData,
            getImageData: getImageData,
            getCanvas: getCanvas,
            render : cornerstone.renderColorImage,
            rows: height,
            columns: width,
            height: height,
            width: width,
            color: true,
            columnPixelSpacing: 1.0,
            rowPixelSpacing: 1.0,
            invert: false,
            sizeInBytes : width * height * 4
        };

        return {
            promise: new Promise((resolve) => resolve(image)),
            cancelFn: undefined
        }
    }

    cornerstone.registerImageLoader('colorImageLoader', loadImage);

    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    function onImageRendered(e) {
        const eventData = e.detail;
        document.getElementById('renderTime').textContent = "Render Time:" + eventData.renderTimeInMs + " ms";
    }
    element.addEventListener('cornerstoneimagerendered', onImageRendered);

    // load image and display it
    const imageId = "colorImageLoader://1";
    cornerstone.loadAndCacheImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);

        // add event handlers to mouse move to adjust window/center
        element.addEventListener('mousedown', function (e) {
            let lastX = e.pageX;
            let lastY = e.pageY;

            function mouseMoveHandler(e) {
                const deltaX = e.pageX - lastX;
                const deltaY = e.pageY - lastY;
                lastX = e.pageX;
                lastY = e.pageY;

                let viewport = cornerstone.getViewport(element);
                viewport.voi.windowWidth += (deltaX / viewport.scale);
                viewport.voi.windowCenter += (deltaY / viewport.scale);
                cornerstone.setViewport(element, viewport);
            }

            function mouseUpHandler() {
                document.removeEventListener('mousemove', mouseMoveHandler);
                document.removeEventListener('mouseup', mouseUpHandler);
            }

            document.addEventListener('mousemove', mouseMoveHandler);
            document.addEventListener('mouseup', mouseUpHandler);
        });
    });
</script>
</html>

十六、本示例说明如何将动态生成的图像与基石集成在一起。动态图像生成器是可以在客户端生成新图像的一种。这可用于进行图像融合以及MPR或体积渲染。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        dynamicImage/index.html
    </h1>

    This example shows how to integrate dynamically generated images with cornerstone.  A dynamic image generator
    is one that can produce new images on the client side.  This could be used to do image fusion as well as
    MPR or Volume Rendering.

    <br>
    <br>

    <button id="opacity25" class="btn">Opacity .25</button>
    <button id="opacity75" class="btn">Opacity .75</button>

    <br>
    <br>

    <div id="dicomImage" style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<script>
    function getPixelData() {
        const width = 256;
        const height = 256;
        const numPixels = width * height;
        const pixelData = new Uint16Array(numPixels);
        let index = 0;
        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                pixelData[index] = ((x) % 256) * this.data.opacity;
                index++;
            }
        }

        return pixelData;
    }

    const dynamicImage = {
        imageId: "notneeded",
        minPixelValue: 0,
        maxPixelValue: 255,
        slope: 1.0,
        intercept: 0,
        windowCenter: 127,
        windowWidth: 256,
        render: cornerstone.renderGrayscaleImage,
        getPixelData: getPixelData,
        rows: 256,
        columns: 256,
        height: 256,
        width: 256,
        color: false,
        columnPixelSpacing: 1.0,
        rowPixelSpacing: 1.0,
        invert: false,
        sizeInBytes: 256 * 256 * 2,
        data: {
            opacity: 0.5
        }
     };

    // image enable the element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);
    cornerstone.displayImage(element, dynamicImage);

    document.getElementById('opacity25').addEventListener('click', function () {
        dynamicImage.data.opacity = .25;
        cornerstone.updateImage(element, true);
    });

    document.getElementById('opacity75').addEventListener('click', function () {
        dynamicImage.data.opacity = .75;
        cornerstone.updateImage(element, true);
    });
</script>
</html>

十七、这是图像翻转和旋转的示例。
在此示例中,图像可以翻转(水平/垂直)或旋转(顺时针/逆时针)


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        fliprotate/index.html
    </h1>

    This is an example of image flips and rotations

    <br>

    In this example,the image can be flipped (Horizontal/Vertical) or rotated (Clockwise/Anti-clockwise)

    <br>
    <br>

    <button id="hFlip" type="button" class="btn btn-default">HFlip</button>
    <button id="vFlip" type="button" class="btn btn-default">VFlip</button>
    <button id="lRotate" type="button" class="btn btn-default">Rotate Left</button>
    <button id="rRotate" type="button" class="btn btn-default">Rotate Right</button>
    <button id="reset" type="button" class="btn btn-default">Reset</button>

    <br>
    <br>

    <div id="dicomImage" style="width:512px;height:512px"
         oncontextmenu="return false"
         onmousedown="return false">
    </div>
    <div><span id="coords"></span></div>

</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../exampleImageIdLoader.js"></script>

<script>
    // image enable the dicomImage element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    //load the image and display it
    const imageId = 'example://1';
    cornerstone.loadImage(imageId).then(function(image) {
        cornerstone.displayImage(element, image);
    });

    // Add event handlers to flip or rotate the image
    document.getElementById('hFlip').addEventListener('click', function (e) {
        const viewport = cornerstone.getViewport(element);
        viewport.hflip = !viewport.hflip;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('vFlip').addEventListener('click', function (e) {
        const viewport = cornerstone.getViewport(element);
        viewport.vflip = !viewport.vflip;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('lRotate').addEventListener('click', function (e) {
        const viewport = cornerstone.getViewport(element);
        viewport.rotation-=90;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('rRotate').addEventListener('click', function (e) {
        const viewport = cornerstone.getViewport(element);
        viewport.rotation+=90;
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('reset').addEventListener('click', function (e) {
        cornerstone.reset(element);
    });

    element.addEventListener('mousemove', function(event) {
        const pixelCoords = cornerstone.pageToPixel(element, event.pageX, event.pageY);
        document.getElementById('coords').textContent = "pageX=" + event.pageX + ", pageY=" + event.pageY + ", pixelX=" + pixelCoords.x + ", pixelY=" + pixelCoords.y;
    });
</script>
</html>

十八、这是带有基于HTML的叠加层的交互式系列滚动,平移,缩放和窗口/级别的示例。

控制项:

  • 左键拖动-窗口/级别

  • 鼠标中键拖动-平移

  • 右键单击拖动-缩放

  • 鼠标滚轮-滚动图像

    
    <!DOCTYPE HTML>
    <html>
    <head>
        <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
        <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
    
        <style>
            .overlay {
                /* prevent text selection on overlay */
                -webkit-touch-callout: none;
                -webkit-user-select: none;
                -khtml-user-select: none;
                -moz-user-select: none;
                -ms-user-select: none;
                user-select: none;
    
                /* ignore pointer event on overlay */
                pointer-events: none;
            }
        </style>
    </head>
    <body>
    <div class="container">
    
        <h1>
            scrollzoompanwl/index.html
        </h1>
    
        This is an example of interactive series scroll, pan, zoom and window/level with HTML
        based overlays.
    
        <br>
        <br>
    
        Controls:
        <ul>
            <li>Left click drag - window/level</li>
            <li>Middle Mouse button drag - pan</li>
            <li>Right click drag - zoom</li>
            <li>Mouse wheel - scroll images</li>
        </ul>
    
        <button id="x256" class="btn">256x256</button>
        <button id="x512" class="btn">512x512</button>
        <button id="invert" class="btn">Toggle Invert</button>
        <button id="interpolation" class="btn">Toggle Interpolation</button>
        <button id="hflip" class="btn">Horizontal Flip</button>
        <button id="vflip" class="btn">Vertical Flip</button>
        <button id="rotate" class="btn">Rotate 90</button>
    
        <br>
        <br>
    
        <div id="dicomImageWrapper" style="width:512px;height:512px;position:relative;color:white"
             oncontextmenu="return false"
             onmousedown="return false">
    
            <div id="dicomImage"
                 style="width:512px;height:512px;top:0px;left:0px;position:absolute">
            </div>
    
            <div id="topleft" class="overlay" style="position:absolute;top:0px;left:0px">
                Patient Name
            </div>
            <div id="topright" class="overlay" style="position:absolute;top:0px;right:0px">
                Render Time:
            </div>
            <div id="bottomright" class="overlay" style="position:absolute;bottom:0px;right:0px">
                Zoom:
            </div>
            <div id="bottomleft" class="overlay" style="position:absolute;bottom:0px;left:0px">
                WW/WC:
            </div>
        </div>
    
        <div><span id="coords"></span></div>
    
    </div>
    </body>
    
    <!-- include the cornerstone library -->
    <script src="../../dist/cornerstone.js"></script>
    <script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>
    
    <!-- include special code for these examples which provides images -->
    <script src="../exampleImageIdLoader.js"></script>
    
    <script>
        const imageIds = [
            'example://1',
            'example://2'
        ];
    
        let currentImageIndex = 0;
    
        // updates the image display
        function updateTheImage(imageIndex) {
            return cornerstone.loadAndCacheImage(imageIds[imageIndex]).then(function(image) {
                currentImageIndex = imageIndex;
                const viewport = cornerstone.getViewport(element);
                cornerstone.displayImage(element, image, viewport);
            });
        }
    
        // image enable the element
        const element = document.getElementById('dicomImage');
        cornerstone.enable(element);
    
        // setup handlers before we display the image
        function onImageRendered(e) {
            const eventData = e.detail;
    
            // set the canvas context to the image coordinate system
            cornerstone.setToPixelCoordinateSystem(eventData.enabledElement, eventData.canvasContext);
    
            // NOTE: The coordinate system of the canvas is in image pixel space.  Drawing
            // to location 0,0 will be the top left of the image and rows,columns is the bottom
            // right.
            const context = eventData.canvasContext;
            context.beginPath();
            context.strokeStyle = 'white';
            context.lineWidth = .5;
            context.rect(128, 90, 50, 60);
            context.stroke();
            context.fillStyle = "white";
            context.font = "6px Arial";
            context.fillText("Tumor Here", 128, 85);
    
            document.getElementById('topright').textContent = "Render Time:" + eventData.renderTimeInMs + " ms";
            document.getElementById('bottomleft').textContent = "WW/WL:" + Math.round(eventData.viewport.voi.windowWidth) + "/" + Math.round(eventData.viewport.voi.windowCenter);
            document.getElementById('bottomright').textContent = "Zoom:" + eventData.viewport.scale.toFixed(2);
    
        }
        element.addEventListener('cornerstoneimagerendered', onImageRendered);
    
        // load and display the image
        const imagePromise = updateTheImage(0);
    
        // add handlers for mouse events once the image is loaded.
        imagePromise.then(function() {
    
            // add event handlers to pan image on mouse move
            element.addEventListener('mousedown', function (e) {
                let lastX = e.pageX;
                let lastY = e.pageY;
                const mouseButton = e.which;
    
                function mouseMoveHandler(e) {
                  const deltaX = e.pageX - lastX;
                  const deltaY = e.pageY - lastY;
                  lastX = e.pageX;
                  lastY = e.pageY;
    
                  if (mouseButton === 1) {
                    let viewport = cornerstone.getViewport(element);
                    viewport.voi.windowWidth += (deltaX / viewport.scale);
                    viewport.voi.windowCenter += (deltaY / viewport.scale);
                    cornerstone.setViewport(element, viewport);
                  } else if (mouseButton === 2) {
                    let viewport = cornerstone.getViewport(element);
                    viewport.translation.x += (deltaX / viewport.scale);
                    viewport.translation.y += (deltaY / viewport.scale);
                    cornerstone.setViewport(element, viewport);
                  } else if (mouseButton === 3) {
                    let viewport = cornerstone.getViewport(element);
                    viewport.scale += (deltaY / 100);
                    cornerstone.setViewport(element, viewport);
                  }
                }
    
                function mouseUpHandler() {
                  document.removeEventListener('mouseup', mouseUpHandler);
                  document.removeEventListener('mousemove', mouseMoveHandler);
                }
    
                document.addEventListener('mousemove', mouseMoveHandler);
                document.addEventListener('mouseup', mouseUpHandler);
            });
    
            const mouseWheelEvents = ['mousewheel', 'DOMMouseScroll'];
            mouseWheelEvents.forEach(function(eventType) {
                element.addEventListener(eventType, function (e) {
                    // 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) {
                        if (currentImageIndex === 0) {
                            updateTheImage(1);
                        }
                    } else {
                        if (currentImageIndex === 1) {
                            updateTheImage(0);
                        }
                    }
    
                    // Prevent page from scrolling
                    return false;
                });
            });
    
            // Add event handler to the ww/wc apply button
            document.getElementById('x256').addEventListener('click', function (e) {
                element.style.width = '256px';
                element.style.height = '256px';
                cornerstone.resize(element);
            });
    
            document.getElementById('x512').addEventListener('click', function (e) {
                element.style.width = '512px';
                element.style.height = '512px';
                cornerstone.resize(element);
            });
    
            document.getElementById('invert').addEventListener('click', function (e) {
                const viewport = cornerstone.getViewport(element);
                viewport.invert = !viewport.invert;
                cornerstone.setViewport(element, viewport);
            });
    
            document.getElementById('interpolation').addEventListener('click', function (e) {
                const viewport = cornerstone.getViewport(element);
                viewport.pixelReplication = !viewport.pixelReplication;
                cornerstone.setViewport(element, viewport);
            });
            document.getElementById('hflip').addEventListener('click', function (e) {
                const viewport = cornerstone.getViewport(element);
                viewport.hflip = !viewport.hflip;
                cornerstone.setViewport(element, viewport);
            });
            document.getElementById('vflip').addEventListener('click', function (e) {
                const viewport = cornerstone.getViewport(element);
                viewport.vflip = !viewport.vflip;
                cornerstone.setViewport(element, viewport);
            });
            document.getElementById('rotate').addEventListener('click', function (e) {
                const viewport = cornerstone.getViewport(element);
                viewport.rotation += 90;
                cornerstone.setViewport(element, viewport);
            });
    
            element.addEventListener('mousemove', function(event) {
                const pixelCoords = cornerstone.pageToPixel(element, event.pageX, event.pageY);
                document.getElementById('coords').textContent = "pageX=" + event.pageX + ", pageY=" + event.pageY + ", pixelX=" + pixelCoords.x + ", pixelY=" + pixelCoords.y;
            });
        });
    </script>
    </html>
    
    

    十九、这是在基石中使用WebGL的示例

    
        <!DOCTYPE HTML>
    <html>
    <head>
        <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
        <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container">
    
        <h1>
            WebGL Example
        </h1>
    
        This is an example of WebGL use in cornerstone
    
        <br>
        <br>
    
        <div class="row">
            <div class="col-xs-6">
                <h4>WebGL</h4>
    
                <div id="dicomImageWebGL"
                     style="width:512px;height:512px"
                     oncontextmenu="return false"
                     onmousedown="return false">
                </div>
    
                <div class="wwwc">WW/WC:</div>
                <div class="renderTime">Render Time:</div>
            </div>
            <div class="col-xs-6">
                <h4>Canvas</h4>
    
                <div id="dicomImage"
                     style="width:512px;height:512px"
                     oncontextmenu="return false"
                     onmousedown="return false">
                </div>
    
                <div class="wwwc">WW/WC:</div>
                <div class="renderTime">Render Time:</div>
            </div>
        </div>
    
    </div>
    </body>
    
    <!-- include the cornerstone library -->
    <script src="../../dist/cornerstone.js"></script>
    <script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>
    
    <!-- include special code for these examples which provides images -->
    <script src="../exampleImageIdLoader.js"></script>
    
    <script>
        const element = document.getElementById('dicomImage');
        const elementWebGL = document.getElementById('dicomImageWebGL');
    
        // setup handlers before we display the image
        function onImageRendered(e) {
            const eventData = e.detail;
    
            // set the canvas context to the image coordinate system
            cornerstone.setToPixelCoordinateSystem(eventData.enabledElement, eventData.canvasContext);
    
            const parent = eventData.element.parentNode;
            parent.querySelector('.renderTime').textContent = "Render Time:" + eventData.renderTimeInMs + " ms";
            parent.querySelector('.wwwc').textContent = "WW/WL:" + Math.round(eventData.viewport.voi.windowWidth)
                + "/" + Math.round(eventData.viewport.voi.windowCenter);
        }
    
        element.addEventListener('cornerstoneimagerendered', onImageRendered);
        elementWebGL.addEventListener('cornerstoneimagerendered', onImageRendered);
    
        const imageId = 'example://1';
    
        cornerstone.enable(element);
    
        cornerstone.loadAndCacheImage(imageId).then(function(image) {
            cornerstone.displayImage(element, image);
        });
    
        const options = {
            renderer: 'webgl'
        };
    
        cornerstone.enable(elementWebGL, options);
    
        cornerstone.loadAndCacheImage(imageId).then(function(image) {
            cornerstone.displayImage(elementWebGL, image);
        });
    
    
        const elements = [element, elementWebGL];
        elements.forEach(function(elem) {
          // add event handlers to mouse move to adjust window/center
          elem.addEventListener('mousedown', function (e) {
            let lastX = e.pageX;
            let lastY = e.pageY;
    
            function mouseMoveHandler(e) {
              const deltaX = e.pageX - lastX;
              const deltaY = e.pageY - lastY;
              lastX = e.pageX;
              lastY = e.pageY;
    
              let viewport = cornerstone.getViewport(elem);
              viewport.voi.windowWidth += (deltaX / viewport.scale);
              viewport.voi.windowCenter += (deltaY / viewport.scale);
              cornerstone.setViewport(elem, viewport);
            }
    
            function mouseUpHandler() {
              document.removeEventListener('mousemove', mouseMoveHandler);
              document.removeEventListener('mouseup', mouseUpHandler);
            }
    
            document.addEventListener('mousemove', mouseMoveHandler);
            document.addEventListener('mouseup', mouseUpHandler);
          });
        });
    </script>
    </html>
    
    

    二十、本示例向您展示如何使用预定义的颜色图或创建自定义查找表,并使用它们创建错误的颜色映射。

    
    <!DOCTYPE HTML>
    <html>
    <head>
        <!-- twitter bootstrap CSS stylesheet - not required by cornerstone -->
        <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container">
    
        <h1>
            falseColorMapping/index.html
        </h1>
    
        This example shows you how to use the pre-defined colormaps or create a custom lookup table and use them to create a false color mapping
    
        <div class="row">
            <div class="col-xs-10">
                <div style="width:512px; padding-top: 5px;">
                    <canvas id="colorbar" width="512px" height="20px"></canvas>
                </div>
    
                <div id="dicomImage"
                     style="width:512px;height:512px"
                     oncontextmenu="return false"
                     onmousedown="return false">
                </div>
            </div>
            <div class="col-xs-2">
                <label for="colormaps"> Colormap </label>
                <select id="colormaps" style="width:100%">
                    <option value="">Select...</option>
                </select>
            </div>
        </div>
    </div>
    </body>
    
    <!-- include the cornerstone library -->
    <script src="../../dist/cornerstone.js"></script>
    <script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>
    
    <!-- include special code for these examples which provides images -->
    <script src="../exampleImageIdLoader.js"></script>
    
    <script>
        // Populate colormap dropdown with all the default ones available
        // in cornerstone and also a "Custom" option
        function fillColormapsList() {
            const dropdown = document.getElementById('colormaps');
            const colormapsList = cornerstone.colors.getColormapsList();
    
            const addOption = function(id, name, disabled) {
                const option = document.createElement("OPTION");
                option.value = id;
                option.textContent = name;
                option.disabled = !!disabled;
                dropdown.append(option);
            };
    
            colormapsList.forEach(function(colormapItem) {
                addOption(colormapItem.id, colormapItem.name);
            });
    
            // Horizontal Line
            addOption('', '──────────', true);
    
            addOption('custom', 'Custom');
        }
    
        // image enable the dicomImage element
        const element = document.getElementById('dicomImage');
        cornerstone.enable(element);
    
        const imageId = 'example://1';
    
        // Load the example image and display it
        cornerstone.loadImage(imageId).then(function(image) {
            cornerstone.displayImage(element, image);
    
            // add event handlers to pan image on mouse move
            element.addEventListener('mousedown', function (e) {
                let lastX = e.pageX;
                let lastY = e.pageY;
                const mouseButton = e.which;
    
                function mouseMoveHandler(e) {
                    const deltaX = e.pageX - lastX;
                    const deltaY = e.pageY - lastY;
                    lastX = e.pageX;
                    lastY = e.pageY;
    
                    if (mouseButton === 1) {
                        let viewport = cornerstone.getViewport(element);
                        viewport.voi.windowWidth += (deltaX / viewport.scale);
                        viewport.voi.windowCenter += (deltaY / viewport.scale);
                        cornerstone.setViewport(element, viewport);
                    } else if (mouseButton === 2) {
                        let viewport = cornerstone.getViewport(element);
                        viewport.translation.x += (deltaX / viewport.scale);
                        viewport.translation.y += (deltaY / viewport.scale);
                        cornerstone.setViewport(element, viewport);
                    } else if (mouseButton === 3) {
                        let viewport = cornerstone.getViewport(element);
                        viewport.scale += (deltaY / 100);
                        cornerstone.setViewport(element, viewport);
                    }
                }
    
                function mouseUpHandler() {
                    document.removeEventListener('mouseup', mouseUpHandler);
                    document.removeEventListener('mousemove', mouseMoveHandler);
                }
    
                document.addEventListener('mousemove', mouseMoveHandler);
                document.addEventListener('mouseup', mouseUpHandler);
            });
        });
    
        // Dropdown listener to get the new colormap
        // selected by the user and update the image
        function colormapChanged() {
            const viewport = cornerstone.getViewport(element);
            const colormapId = document.getElementById('colormaps').value;
            let colormap;
    
            // Use selected the first option ("Select...")
            if (colormapId === '') {
                return;
            } else if(colormapId === 'custom') {
                colormap = getCustomLookupTable();
            } else {
                colormap = cornerstone.colors.getColormap(colormapId);
            }
    
            viewport.colormap = colormap;
            cornerstone.setViewport(element, viewport);
            cornerstone.updateImage(element, true);
    
            // Update the colorbar at the top of the image
            updateColorbar(colormap);
        }
    
        function getCustomLookupTable(minPixelValue, maxPixelValue) {
            const colormap = cornerstone.colors.getColormap('myCustomColorMap');
            colormap.setNumberOfColors(6);
    
            // You can also use `addColor` but in this case it wouldn't work.
            // Any colormap returned by `getColormap` lasts forever (global) and
            // calling `addColor` would result in duplicated colors.
            colormap.insertColor(0, [188, 252, 201, 255]); // Banana
            colormap.insertColor(1, [245, 222, 179, 255]); // Wheat
            colormap.insertColor(2, [255, 125,  64, 255]); // Flesh
            colormap.insertColor(3, [135,  38,  87, 255]); // Raspberry
            colormap.insertColor(4, [227, 206,  87, 255]); // Mint
            colormap.insertColor(5, [ 51, 160, 201, 255]); // Peacock
    
            return colormap;
        }
    
        // Update the colorbar at the top of the image
        function updateColorbar(colormap) {
            const lookupTable = colormap.createLookupTable();
            const canvas = document.getElementById('colorbar');
            const ctx = canvas.getContext('2d');
            const height = canvas.height;
            const width = canvas.width;
            const colorbar = ctx.createImageData(512, 20);
    
            // Set the min and max values then the lookup table
            // will be able to return the right color for this range
            lookupTable.setTableRange(0, width);
    
            // Update the colorbar pixel by pixel
            for(let col = 0; col < width; col++) {
                const color = lookupTable.mapValue(col);
    
                for(let row = 0; row < height; row++) {
                    const pixel = (col + row * width) * 4;
                    colorbar.data[pixel] = color[0];
                    colorbar.data[pixel+1] = color[1];
                    colorbar.data[pixel+2] = color[2];
                    colorbar.data[pixel+3] = color[3];
                }
            }
    
            ctx.putImageData(colorbar, 0, 0);
        }
    
        document.getElementById('colormaps').addEventListener('change', colormapChanged);
    
        fillColormapsList();
    </script>
    </html>
    
    

二十一、本示例说明如何添加图层并与图层交互。


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        Composite Images
    </h1>

    This example shows you how to add and interact with layers.
    <div class="row">
        <div class="col-xs-2">
            <label>Viewport Values:</label>
            <div><span>Viewport Scale: </span><span id="layerViewportScale"></span></div>
        </div>
        <div class="col-xs-4">
            <label>Layer CT Values:</label>
            <div><span>Viewport Scale: </span><span id="layer1ViewportScale"></span></div>
            <div><span>Layer Viewport Scale: </span><span id="layer1LayerViewportScale"></span></div>
            <div><span>Layer Sync Scale: </span><span id="layer1LayerSyncScale"></span></div>
        </div>
        <div class="col-xs-4">
            <label>Layer PET Values:</label>
            <div><span>Layer Viewport Scale: </span><span id="layer2LayerViewportScale"></span></div>
            <div><span>Layer Sync Scale: </span><span id="layer2LayerSyncScale"></span></div>
        </div>
    </div>
    <div class="row" style="padding-top: 20px;">
        <div class="col-xs-10">
            <div id="dicomImage"
                 style="width:512px;height:512px;top:0px;left:0px;position:absolute"
                 oncontextmenu="return false"
                 onmousedown="return false">
            </div>
        </div>
        <div class="col-xs-2">
            <div style="margin-bottom: 15px;">
                <label for="syncViewports"> Sync Viewports
                    <input id="syncViewports" name="syncViewports" type="checkbox" checked/>
                </label>
                <br>
            </div>

            <label for="layers">Select active layer</label>
            <select name="layers" id="layers" size="2" style="width: 100%; min-width: 150px;"></select>
            <div id="properties" style="width: 100%; min-width: 150px; margin-top: 15px;">
                <label>Layer Properties</label>
                <div style="width: 100%; padding: 5px 5px 5px 10px;">
                    <div style="margin-bottom: 15px;">
                        <label for="visible"> Visible
                            <input name="visible" type="checkbox" checked/>
                        </label>
                        <br>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <label for="colormaps"> Colormap </label>
                        <select id="colormaps" style="width:100%">
                            <option value="">None</option>
                        </select>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <label for="imageOpacity"> Opacity</label>
                        <input id="imageOpacity" type="range" class="range" min=0 max=1 step=0.1 value=0>
                    </div>
                </div>
            </div>
        </div>
        <!-- <div class="col-xs-12">
        </div> -->
    </div>
</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../petctImageIdLoader.js"></script>
<script src="../petctMetaDataProvider.js"></script>

<script>
    // Enable the dicomImage element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // JSON with all layers to be loaded
    // The `name` option is used only by this example and
    // cornerstone doesn't even know that it exists.
    // You can add any option you want to `options` object.
    const layers = [{
            imageId: 'ct://1',
            options: {
                name: 'CT'
            }
        }, {
            imageId: 'pet://1',
            options: {
                name: 'PET',
                opacity: 0.7,
                viewport: {
                    colormap: 'hotIron',
                    voi: {
                        windowWidth: 30,
                        windowCenter: 16
                    }
                }
            }
        }
    ];

    // This is the main function responsible for loading all layers
    // This method will wait for all images to be loaded (`loadImages`)
    // before adding the layers
    function loadLayers() {
        loadImages().then(function(images) {
            images.forEach(function(image, index) {
                const layer = layers[index];
                const layerId = cornerstone.addLayer(element, image, layer.options);

                cornerstone.updateImage(element);
                console.log('Layer ' + index + ': ' + layerId);
            });

            // Update dropdown size to make all layers name visible
            const layersDropdown = document.getElementById('layers');
            layersDropdown.size = layers.length;

            // Listen to `change` event to set the selected layer as active
            layersDropdown.addEventListener('change', function(event) {
                const layerId = event.currentTarget.value;
                cornerstone.setActiveLayer(element, layerId);
            });
        });
    }

    // This method loads the image of each layer and resolve the
    // promise only after getting all of them loaded
    function loadImages() {
        const promises = [];

        layers.forEach(function(layer) {
            const loadPromise = cornerstone.loadAndCacheImage(layer.imageId);
            promises.push(loadPromise);
        });

        return Promise.all(promises);
    }

    // Select the right layer in the dropdown
    function updateSelectedLayer(layerId) {
        const layers = document.getElementById('layers');
        const currentLayerId = layers.value;

        if(currentLayerId !== layerId) {
            layers.value = layerId;

            // Trigger a change event
            const event = new Event('change');
            element.dispatchEvent(event);
        }
    }

    // Listen to `change` event to activate/deactivate the viewport synchronization
    document.querySelector('input[name=syncViewports]').addEventListener('change', function(event) {
        const enabledElement = cornerstone.getEnabledElement(element);
        enabledElement.syncViewports = event.currentTarget.checked;
        cornerstone.updateImage(element);
    });

    document.getElementById('colormaps').addEventListener('change', function() {
        const layer = cornerstone.getActiveLayer(element);
        layer.viewport.colormap = document.getElementById('colormaps').value;
        cornerstone.updateImage(element);
    });

    // Listen to `change` event to update the opacity of the active layer
    document.getElementById("imageOpacity").addEventListener('change', function(event) {
        const layer = cornerstone.getActiveLayer(element);
        layer.options.opacity = parseFloat(event.currentTarget.value);
        cornerstone.updateImage(element);
    });

    // Listen to `change` event to update the visibility of the active layer
    document.querySelector('input[name=visible]').addEventListener('change', function(event) {
        const layer = cornerstone.getActiveLayer(element);
        layer.options.visible = event.currentTarget.checked;
        cornerstone.updateImage(element);
    });

    // This event will be called every time a layer is added through cornerstone.addLayer
    // The layer is added to the dropdown to make it possible to select and interact with it
    element.addEventListener('cornerstonelayeradded', function(e) {
        const eventData = e.detail;
        const layer = cornerstone.getLayer(eventData.element, eventData.layerId);
        const layers = document.getElementById('layers');

        const layerOption = document.createElement("OPTION");
        layerOption.value = layer.layerId;
        layerOption.textContent = layer.options.name;

        // Set the layer as selected in case its the the first layer to be added
        if(layers.childElementCount === 0) {
            layerOption.checked = true;
        }

        layers.appendChild(layerOption);
    });

    // This event will be called every time cornerstone.setActiveLayer is called
    // We need to load the layer properties and update the selected layer in the dropdown
    element.addEventListener('cornerstoneactivelayerchanged', function(e) {
        const eventData = e.detail;
        const layer = cornerstone.getActiveLayer(element);
        const colormap = layer.viewport.colormap || '';
        const opacity = layer.options.opacity == null ? 1 : layer.options.opacity;

        // Restore all properties for the active layer
        document.getElementById('imageOpacity').value = opacity;
        document.querySelector("input[name=visible]").checked = layer.options.visible === undefined ? true : layer.options.visible;
        document.getElementById('colormaps').value = colormap;

        updateSelectedLayer(eventData.layerId);
    });


    // Populate colormap dropdown with all the default ones
    function fillColormapsList() {
        const dropdown = document.getElementById('colormaps');
        const colormapsList = cornerstone.colors.getColormapsList();

        const addOption = function(id, name) {
            const option = document.createElement("OPTION");
            option.value = id;
            option.textContent = name;

            dropdown.append(option);
        };

        colormapsList.forEach(function(colormapItem) {
            addOption(colormapItem.id, colormapItem.name);
        });
    }

      // add event handlers to pan image on mouse move
      element.addEventListener('mousedown', function (e) {
        let lastX = e.pageX;
        let lastY = e.pageY;
        const mouseButton = e.which;

        function mouseMoveHandler(e) {
          const deltaX = e.pageX - lastX;
          const deltaY = e.pageY - lastY;
          lastX = e.pageX;
          lastY = e.pageY;

          if (mouseButton === 1) {
            let viewport = cornerstone.getViewport(element);
            viewport.voi.windowWidth += (deltaX / viewport.scale);
            viewport.voi.windowCenter += (deltaY / viewport.scale);
            cornerstone.setViewport(element, viewport);
          } else if (mouseButton === 2) {
            let viewport = cornerstone.getViewport(element);
            viewport.translation.x += (deltaX / viewport.scale);
            viewport.translation.y += (deltaY / viewport.scale);
            cornerstone.setViewport(element, viewport);
          } else if (mouseButton === 3) {
            let viewport = cornerstone.getViewport(element);
            viewport.scale += (deltaY / 100);
            cornerstone.setViewport(element, viewport);

            document.getElementById('layerViewportScale').innerText = viewport.scale;
          }

          const layer1 = cornerstone.getLayers(element)[0];
          const layer2 = cornerstone.getLayers(element)[1];

          document.getElementById('layer1LayerViewportScale').innerText = layer1.viewport.scale;
          document.getElementById('layer2LayerViewportScale').innerText = layer2.viewport.scale;
          document.getElementById('layer1LayerSyncScale').innerText = layer1.syncProps.originalScale;
          document.getElementById('layer2LayerSyncScale').innerText = layer2.syncProps.originalScale;
          
        }

        function mouseUpHandler() {
          document.removeEventListener('mouseup', mouseUpHandler);
          document.removeEventListener('mousemove', mouseMoveHandler);
        }

        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
      });

      const mouseWheelEvents = ['mousewheel', 'DOMMouseScroll'];
      mouseWheelEvents.forEach(function(eventType) {
        element.addEventListener(eventType, function (e) {
          // Firefox e.detail > 0 scroll back, < 0 scroll forward
          // chrome/safari e.wheelDelta < 0 scroll back, > 0 scroll forward
          let viewport = cornerstone.getViewport(element);
          if (e.wheelDelta < 0 || e.detail > 0) {
            viewport.scale -= 0.25;
          } else {
            viewport.scale += 0.25;
          }

          cornerstone.setViewport(element, viewport);

          // Prevent page from scrolling
          return false;
        });
      });

    // Start point to load all layers and colormaps and
    // also attach a click listener to each tool
    loadLayers();
    fillColormapsList();
</script>
</html>

二十二、WADO-URI(通过HTTP GET的DICOM P10)


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="../bootstrap.min.css" rel="stylesheet">
    <link href="../cornerstone.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="page-header">
        <h1>Example of displaying a DICOM P10 image using Cornerstone</h1>
        <p class="lead">
            Enter a URL for a DICOM P10 object below to view it using cornerstone.
            <button id='toggleCollapseInfo' class="btn btn-primary" type="button">
                Click for more info
            </button>
        </p>
        <ul>
            <!--
            <li>/cornerstoneWADOImageLoader/examples/testImages/ile/gray16.DCM</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/ile/gray8.DCM</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/ile/ybrFull.DCM</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/rle/paletteColor.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/rle/gray16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/rle/rgb.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/rle/multiframe.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.50/ybrFull.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.50/ybrFull422.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.50/gray8.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.50/multiframe.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.51/grayu16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.57/grayu16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.70/gray8.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg.70/grays16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg2000.90/grayu16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg2000.90/grays16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg2000.90/ybrrct.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg2000.91/grays16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg2000.91/grayu16.dcm</li>
            <li>/cornerstoneWADOImageLoader/examples/testImages/jpeg2000.91/ybrict.dcm</li>
            -->
        </ul>
    </div>
    <div id="collapseInfo" class="collapse" style="display:none;">
        <p>
            This example illustrates how to use the cornerstoneWADOImageLoader to get a DICOM P10
            SOP instance using HTTP and display it in your web browser using cornerstone.
            Not all transfer syntaxes are currently supported,
            <a href="https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/docs/TransferSyntaxes.md">
                click here for the full list.
            </a>
            For WADO-URI requests,
            you can request that the server return the SOP Instance in explicit little endian by
            appending the following query string to your URL:
            <code>&transferSyntax=1.2.840.10008.1.2.1</code>
        </p>
        <P>
            Use the query string parameter <i>frame</i> to specify which frame to display from a multiframe
            object (defaults to the first frame if not specified). <code>?frame=2</code>
        </P>
        <strong>If you get an HTTP error and your URL is correct, it is probably because the server is not configured to
            allow <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross Origin Requests</a>.
            Most browsers will allow you to enable cross domain requests via settings or command line switches,
            you can start chrome with the command line switch <code>--disable-web-security</code> to allow cross origin requests.
            See the  <a href="http://enable-cors.org/">Enable CORS site</a> for information about CORS.
        </strong>
        <br>
        <br>
        <p>
            Looking for a CORS proxy?  Try <a href="https://www.npmjs.com/package/corsproxy">CORSProxy</a>
        </p>
        <strong>Use of this example require IE10+ or any other modern browser.</strong>
        <hr>
    </div>
    <div id="loadProgress">Image Load Progress:</div>

    <div class="row">
        <form id="form" class="form-horizontal">
            <div class="form-group">
                <label class="control-label col-sm-1" for="wadoURL">URL</label>
                <div class="col-sm-8">
                    <input class="form-control" type="text" id="wadoURL" placeholder="Enter WADO URL" value="https://raw.githubusercontent.com/cornerstonejs/cornerstoneWADOImageLoader/master/testImages/CT2_J2KR">
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="downloadAndView" class="btn btn-primary">Download and View</button>
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-2">
                    <button class="form-control" type="button" id="load" class="btn btn-primary">Load</button>
                </div>
                <div class="col-sm-2">
                    <button class="form-control" type="button" id="unload" class="btn btn-primary">Unload</button>
                </div>
                <div class="col-sm-2">
                    <button class="form-control" type="button" id="purge" class="btn btn-primary">Purge Cache</button>
                </div>
            </div>
        </form>
    </div>
    <input type="checkbox" id="toggleModalityLUT">Apply Modality LUT</input>
    <input type="checkbox" id="toggleVOILUT">Apply VOI LUT</input>
    <br>
    <div class="row">
        <div class="col-md-6">
            <div style="width:512px;height:512px;position:relative;color: white;display:inline-block;border-style:solid;border-color:black;"
                 oncontextmenu="return false"
                 class='disable-selection noIbar'
                 unselectable='on'
                 onselectstart='return false;'
                 onmousedown='return false;'>
                <div id="dicomImage"
                     style="width:512px;height:512px;top:0px;left:0px; position:absolute">
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <span>Transfer Syntax: </span><span id="transferSyntax"></span><br>
            <span>SOP Class: </span><span id="sopClass"></span><br>
            <span>Samples Per Pixel: </span><span id="samplesPerPixel"></span><br>
            <span>Photometric Interpretation: </span><span id="photometricInterpretation"></span><br>
            <span>Number Of Frames: </span><span id="numberOfFrames"></span><br>
            <span>Planar Configuration: </span><span id="planarConfiguration"></span><br>
            <span>Rows: </span><span id="rows"></span><br>
            <span>Columns: </span><span id="columns"></span><br>
            <span>Pixel Spacing: </span><span id="pixelSpacing"></span><br>
            <span>Row Pixel Spacing: </span><span id="rowPixelSpacing"></span><br>
            <span>Column Pixel Spacing: </span><span id="columnPixelSpacing"></span><br>
            <span>Bits Allocated: </span><span id="bitsAllocated"></span><br>
            <span>Bits Stored: </span><span id="bitsStored"></span><br>
            <span>High Bit: </span><span id="highBit"></span><br>
            <span>Pixel Representation: </span><span id="pixelRepresentation"></span><br>
            <span>WindowCenter: </span><span id="windowCenter"></span><br>
            <span>WindowWidth: </span><span id="windowWidth"></span><br>
            <span>RescaleIntercept: </span><span id="rescaleIntercept"></span><br>
            <span>RescaleSlope: </span><span id="rescaleSlope"></span><br>
            <span>Basic Offset Table Entries: </span><span id="basicOffsetTable"></span><br>
            <span>Fragments: </span><span id="fragments"></span><br>
            <span>Max Stored Pixel Value: </span><span id="minStoredPixelValue"></span><br>
            <span>Min Stored Pixel Value: </span><span id="maxStoredPixelValue"></span><br>
            <span>Total Time: </span><span id="totalTime"></span><br>
            <span>Load Time: </span><span id="loadTime"></span><br>
            <span>Decode Time: </span><span id="decodeTime"></span><br>
        </div>
    </div>
</div>
</body>

<!-- include the cornerstone library -->
<script src="../cornerstone.min.js"></script>
<SCRIPT src="../cornerstoneMath.min.js"></SCRIPT>
<SCRIPT src="../cornerstoneTools.min.js"></SCRIPT>

<!-- include the dicomParser library as the WADO image loader depends on it -->
<script src="../dicomParser.min.js"></script>

<!-- include the cornerstoneWADOImageLoader library -->
<script src="../../dist/cornerstoneWADOImageLoader.js"></script>

<script src="../dicomfile/uids.js"></script>

<!-- Lines ONLY required for this example to run without building the project -->
<script>window.cornerstoneWADOImageLoader || document.write('<script src="https://unpkg.com/cornerstone-wado-image-loader">\x3C/script>')</script>
<script src="../utils/initializeWebWorkers.js"></script>

<script>
    cornerstoneWADOImageLoader.external.cornerstone = cornerstone;

    cornerstoneWADOImageLoader.configure({
        beforeSend: function(xhr) {
            // Add custom headers here (e.g. auth tokens)
            //xhr.setRequestHeader('APIKEY', 'my auth token');
        }
    });

    var loaded = false;

    function loadAndViewImage(imageId) {
        var element = document.getElementById('dicomImage');

        try {
            var start = new Date().getTime();
            cornerstone.loadAndCacheImage(imageId).then(function(image) {
                console.log(image);
                var viewport = cornerstone.getDefaultViewportForImage(element, image);
                document.getElementById('toggleModalityLUT').checked = (viewport.modalityLUT !== undefined);
                document.getElementById('toggleVOILUT').checked = (viewport.voiLUT !== undefined);
                cornerstone.displayImage(element, image, viewport);
                if(loaded === false) {
                    cornerstoneTools.mouseInput.enable(element);
                    cornerstoneTools.mouseWheelInput.enable(element);
                    cornerstoneTools.wwwc.activate(element, 1); // ww/wc is the default tool for left mouse button
                    cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
                    cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
                    cornerstoneTools.zoomWheel.activate(element); // zoom is the default tool for middle mouse wheel
                    loaded = true;
                }

                function getTransferSyntax() {
                    const value = image.data.string('x00020010');
                    return value + ' [' + uids[value] + ']';
                }

                function getSopClass() {
                    const value = image.data.string('x00080016');
                    return value + ' [' + uids[value] + ']';
                }

                function getPixelRepresentation() {
                    const value = image.data.uint16('x00280103');
                    if(value === undefined) {
                        return;
                    }
                    return value + (value === 0 ? ' (unsigned)' : ' (signed)');
                }

                function getPlanarConfiguration() {
                    const value = image.data.uint16('x00280006');
                    if(value === undefined) {
                        return;
                    }
                    return value + (value === 0 ? ' (pixel)' : ' (plane)');
                }


                document.getElementById('transferSyntax').textContent = getTransferSyntax();
                document.getElementById('sopClass').textContent = getSopClass();
                document.getElementById('samplesPerPixel').textContent = image.data.uint16('x00280002');
                document.getElementById('photometricInterpretation').textContent = image.data.string('x00280004');
                document.getElementById('numberOfFrames').textContent = image.data.string('x00280008');
                document.getElementById('planarConfiguration').textContent = getPlanarConfiguration();
                document.getElementById('rows').textContent = image.data.uint16('x00280010');
                document.getElementById('columns').textContent = image.data.uint16('x00280011');
                document.getElementById('pixelSpacing').textContent = image.data.string('x00280030');
                document.getElementById('rowPixelSpacing').textContent = image.rowPixelSpacing;
                document.getElementById('columnPixelSpacing').textContent = image.columnPixelSpacing;
                document.getElementById('bitsAllocated').textContent = image.data.uint16('x00280100');
                document.getElementById('bitsStored').textContent = image.data.uint16('x00280101');
                document.getElementById('highBit').textContent = image.data.uint16('x00280102');
                document.getElementById('pixelRepresentation').textContent = getPixelRepresentation();
                document.getElementById('windowCenter').textContent = image.data.string('x00281050');
                document.getElementById('windowWidth').textContent = image.data.string('x00281051');
                document.getElementById('rescaleIntercept').textContent = image.data.string('x00281052');
                document.getElementById('rescaleSlope').textContent = image.data.string('x00281053');
                document.getElementById('basicOffsetTable').textContent = image.data.elements.x7fe00010.basicOffsetTable ? image.data.elements.x7fe00010.basicOffsetTable.length : '';
                document.getElementById('fragments').textContent = image.data.elements.x7fe00010.fragments ? image.data.elements.x7fe00010.fragments.length : '';
                document.getElementById('minStoredPixelValue').textContent = image.minPixelValue;
                document.getElementById('maxStoredPixelValue').textContent = image.maxPixelValue;
                var end = new Date().getTime();
                var time = end - start;
                document.getElementById('totalTime').textContent = time + "ms";
                document.getElementById('loadTime').textContent = image.loadTimeInMS + "ms";
                document.getElementById('decodeTime').textContent = image.decodeTimeInMS + "ms";

            }, function(err) {
                alert(err);
            });
        }
        catch(err) {
            alert(err);
        }
    }

    function downloadAndView() {
        let url = document.getElementById('wadoURL').value;

        // prefix the url with wadouri: so cornerstone can find the image loader
        url = "wadouri:" + url;

        // image enable the dicomImage element and activate a few tools
        loadAndViewImage(url);
    }

    cornerstone.events.addEventListener('cornerstoneimageloadprogress', function(event) {
        const eventData = event.detail;
        const loadProgress = document.getElementById('loadProgress');
        loadProgress.textContent = `Image Load Progress: ${eventData.percentComplete}%`;
    });

    function getUrlWithoutFrame() {
        var url = document.getElementById('wadoURL').value;
        var frameIndex = url.indexOf('frame=');
        if(frameIndex !== -1) {
            url = url.substr(0, frameIndex-1);
        }
        return url;
    }

    var element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    document.getElementById('downloadAndView').addEventListener('click', function(e) {
        downloadAndView();
    });
    document.getElementById('load').addEventListener('click', function(e) {
        var url = getUrlWithoutFrame();
        cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.load(url);
    });
    document.getElementById('unload').addEventListener('click', function(e) {
        var url = getUrlWithoutFrame();
        cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.unload(url);
    });

    document.getElementById('purge').addEventListener('click', function(e) {
        cornerstone.imageCache.purgeCache();
    });

    const form = document.getElementById('form');
    form.addEventListener('submit', function() {
        downloadAndView();
        return false;
    });

    document.getElementById('toggleModalityLUT').addEventListener('click', function() {
        var applyModalityLUT = document.getElementById('toggleModalityLUT').checked;
        console.log('applyModalityLUT=', applyModalityLUT);
        var image = cornerstone.getImage(element);
        var viewport = cornerstone.getViewport(element);
        if(applyModalityLUT) {
            viewport.modalityLUT = image.modalityLUT;
        } else {
            viewport.modalityLUT = undefined;
        }
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('toggleVOILUT').addEventListener('click', function() {
        var applyVOILUT = document.getElementById('toggleVOILUT').checked;
        console.log('applyVOILUT=', applyVOILUT);
        var image = cornerstone.getImage(element);
        var viewport = cornerstone.getViewport(element);
        if(applyVOILUT) {
            viewport.voiLUT = image.voiLUT;
        } else {
            viewport.voiLUT = undefined;
        }
        cornerstone.setViewport(element, viewport);
    });

    document.getElementById('toggleCollapseInfo').addEventListener('click', function() {
        if (document.getElementById('collapseInfo').style.display === 'none') {
            document.getElementById('collapseInfo').style.display = 'block';
        } else {
            document.getElementById('collapseInfo').style.display = 'none';
        }
    });
</script>
</html>

23、WADO-URI(通过HTTP GET的DICOM P10)多帧


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="../bootstrap.min.css" rel="stylesheet">

    <link href="../cornerstone.min.css" rel="stylesheet">

</head>
<body>
<div class="container">

    <div class="page-header">
        <h1>Example of displaying a DICOM P10 multiframe images using Cornerstone</h1>
        <p class="lead">
            Enter a URL for a DICOM P10 multiframe sop instance to view it using cornerstone.
            <button id="toggleCollapseInfo" class="btn btn-primary" type="button">
                Click for more info
            </button>
        </p>
    </div>
    <div id="collapseInfo" class="collapse" style="display:none;">
        <p>
            This example illustrates how to use the cornerstoneWADOImageLoader to get a DICOM P10
            SOP instance using HTTP and display it in your web browser using cornerstone.
            Not all transfer syntaxes are currently supported,
            <a href="https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/docs/TransferSyntaxes.md">
                click here for the full list.
            </a>
            For WADO-URI requests,
            you can request that the server return the SOP Instance in explicit little endian by
            appending the following query string to your URL:
            <code>&transferSyntax=1.2.840.10008.1.2.1</code>
        </p>
        <strong>If you get an HTTP error and your URL is correct, it is probably because the server is not configured to
            allow <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross Origin Requests</a>.
            Most browsers will allow you to enable cross domain requests via settings or command line switches,
            you can start chrome with the command line switch <code>--disable-web-security</code> to allow cross origin requests.
            See the  <a href="http://enable-cors.org/">Enable CORS site</a> for information about CORS.
        </strong>
        <br>
        <br>
        <p>
            Looking for a CORS proxy?  Try <a href="https://www.npmjs.com/package/corsproxy">CORSProxy</a>
        </p>
        <strong>Use of this example require IE10+ or any other modern browser.</strong>
        <hr>
    </div>
    <div id="loadProgress">Image Load Progress:</div>

    <div class="row">
        <form id="form" class="form-horizontal">
            <div class="form-group">
                <label class="control-label col-sm-1" for="wadoURL">URL</label>
                <div class="col-sm-8">
                    <input class="form-control" type="text" id="wadoURL" placeholder="Enter WADO URL" value="https://raw.githubusercontent.com/cornerstonejs/cornerstoneWADOImageLoader/master/testImages/CT0012.fragmented_no_bot_jpeg_baseline.51.dcm">
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="downloadAndView" class="btn btn-primary">Download and View</button>
                </div>
            </div>
        </form>
    </div>
    <br>
    <div style="width:512px;height:512px;position:relative;color: white;display:inline-block;border-style:solid;border-color:black;"
         oncontextmenu="return false"
         class='disable-selection noIbar'
         unselectable='on'
         onselectstart='return false;'
         onmousedown='return false;'>
        <div id="dicomImage"
             style="width:512px;height:512px;top:0px;left:0px; position:absolute">
        </div>
    </div>
</div>
</body>

<!-- include the cornerstone library -->
<script src="../cornerstone.min.js"></script>
<SCRIPT src="../cornerstoneMath.min.js"></SCRIPT>
<SCRIPT src="../cornerstoneTools.min.js"></SCRIPT>

<!-- include the dicomParser library as the WADO image loader depends on it -->
<script src="../dicomParser.min.js"></script>

<!-- include the cornerstoneWADOImageLoader library -->
<script src="../../dist/cornerstoneWADOImageLoader.js"></script>

<!-- Lines ONLY required for this example to run without building the project -->
<script>window.cornerstoneWADOImageLoader || document.write('<script src="https://unpkg.com/cornerstone-wado-image-loader">\x3C/script>')</script>
<script src="../utils/initializeWebWorkers.js"></script>

<script>
    cornerstoneWADOImageLoader.external.cornerstone = cornerstone;

    cornerstoneWADOImageLoader.configure({
        beforeSend: function(xhr) {
            // Add custom headers here (e.g. auth tokens)
            //xhr.setRequestHeader('x-auth-token', 'my auth token');
        }
    });

    var loaded = false;

    function loadAndViewImage(url) {
        var element = document.getElementById('dicomImage');

        // since this is a multi-frame example, we need to load the DICOM SOP Instance into memory and parse it
        // so we know the number of frames it has so we can create the stack.  Calling load() will increment the reference
        // count so it will stay in memory until unload() is explicitly called and all other reference counts
        // held by the cornerstone cache are gone.  See below for more info
        cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.load(url, cornerstoneWADOImageLoader.internal.xhrRequest).then(function(dataSet) {
            // dataset is now loaded, get the # of frames so we can build the array of imageIds
            var numFrames = dataSet.intString('x00280008');
            if(!numFrames) {
                alert('Missing element NumberOfFrames (0028,0008)');
                return;
            }

            var imageIds = [];
            var imageIdRoot = 'wadouri:' + url;

            for(var i=0; i < numFrames; i++) {
                var imageId = imageIdRoot + "?frame="+i;
                imageIds.push(imageId);
            }

            var stack = {
                currentImageIdIndex : 0,
                imageIds: imageIds
            };

            // Load and cache the first image frame.  Each imageId cached by cornerstone increments
            // the reference count to make sure memory is cleaned up properly.
            cornerstone.loadAndCacheImage(imageIds[0]).then(function(image) {
                console.log(image);
                // now that we have an image frame in the cornerstone cache, we can decrement
                // the reference count added by load() above when we loaded the metadata.  This way
                // cornerstone will free all memory once all imageId's are removed from the cache
                cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.unload(url);

                cornerstone.displayImage(element, image);
                if(loaded === false) {
                    cornerstoneTools.wwwc.activate(element, 1); // ww/wc is the default tool for left mouse button
                    // Set the stack as tool state
                    cornerstoneTools.addStackStateManager(element, ['stack', 'playClip']);
                    cornerstoneTools.addToolState(element, 'stack', stack);
                    // Start playing the clip
                    // TODO: extract the frame rate from the dataset
                    var frameRate = 10;
                    cornerstoneTools.playClip(element, frameRate);
                    loaded = true;
                }
            }, function(err) {
                alert(err);
            });
            /*}
             catch(err) {
             alert(err);
             }*/
        });

    }

    function downloadAndView() {
        const url = document.getElementById('wadoURL').value;

        // image enable the dicomImage element and activate a few tools
        loadAndViewImage(url);

        return false;
    }

    cornerstone.events.addEventListener('cornerstoneimageloadprogress', function(event) {
        const eventData = event.detail;
        const loadProgress = document.getElementById('loadProgress');
        loadProgress.textContent = `Image Load Progress: ${eventData.percentComplete}%`;
    });

    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);
    cornerstoneTools.mouseInput.enable(element);
    cornerstoneTools.mouseWheelInput.enable(element);

    document.getElementById('downloadAndView').addEventListener('click', function(e) {
        downloadAndView();
    });

    const form = document.getElementById('form');
    form.addEventListener('submit', function() {
        downloadAndView();
        return false;
    });

    document.getElementById('toggleCollapseInfo').addEventListener('click', function() {
        if (document.getElementById('collapseInfo').style.display === 'none') {
            document.getElementById('collapseInfo').style.display = 'block';
        } else {
            document.getElementById('collapseInfo').style.display = 'none';
        }
    });
</script>
</html>

24、睡眠任务


<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="../bootstrap.min.css" rel="stylesheet">

    <link href="../cornerstone.min.css" rel="stylesheet">

</head>
<body>
<div class="container">

    <div class="page-header">
        <h1>Example of using a custom web worker</h1>
        <p class="lead">
            Enter a URL for a DICOM P10 object below to view it using cornerstone.
            <button id="toggleCollapseInfo" class="btn btn-primary" type="button">
                Click for more info
            </button>
        </p>
    </div>
    <div id="collapseInfo" class="collapse" style="display:none;">
        <p>
            This example illustrates how to use the cornerstoneWADOImageLoader to get a DICOM P10
            SOP instance using HTTP and display it in your web browser using cornerstone.
            Not all transfer syntaxes are currently supported,
            <a href="https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/docs/TransferSyntaxes.md">
                click here for the full list.
            </a>
            For WADO-URI requests,
            you can request that the server return the SOP Instance in explicit little endian by
            appending the following query string to your URL:
            <code>&transferSyntax=1.2.840.10008.1.2.1</code>
        </p>
        <P>
            Use the query string parameter <i>frame</i> to specify which frame to display from a multiframe
            object (defaults to the first frame if not specified). <code>?frame=2</code>
        </P>
        <strong>If you get an HTTP error and your URL is correct, it is probably because the server is not configured to
            allow <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross Origin Requests</a>.
            Most browsers will allow you to enable cross domain requests via settings or command line switches,
            you can start chrome with the command line switch <code>--disable-web-security</code> to allow cross origin requests.
            See the  <a href="http://enable-cors.org/">Enable CORS site</a> for information about CORS.
        </strong>
        <br>
        <br>
        <p>
            Looking for a CORS proxy?  Try <a href="https://www.npmjs.com/package/corsproxy">CORSProxy</a>
        </p>
        <strong>Use of this example require IE10+ or any other modern browser.</strong>
        <hr>
    </div>

    <div class="row">
        <form id="form" class="form-horizontal">
            <div class="form-group">
                <label class="control-label col-sm-1" for="wadoURL">URL</label>
                <div class="col-sm-8">
                    <input class="form-control" type="text" id="wadoURL" placeholder="Enter WADO URL" value="https://raw.githubusercontent.com/cornerstonejs/cornerstoneWADOImageLoader/master/testImages/CT2_J2KR">
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="downloadAndView" class="btn btn-primary">Download and View</button>
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="startWebWorker" class="btn btn-primary">Start 1 Sleep Tasks</button>
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="start10WebWorkers" class="btn btn-primary">Start 10 Sleep Tasks</button>
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="sharpen" class="btn btn-primary">Sharpen Image</button>
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="edgeDetect" class="btn btn-primary">Edge Enhance</button>
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="boxBlur" class="btn btn-primary">Box Blur</button>
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="gaussianBlur" class="btn btn-primary">Gaussian Blur</button>
                </div>
                <div class="col-sm-3">
                    <button class="form-control" type="button" id="emboss" class="btn btn-primary">Emboss</button>
                </div>

                <div class="col-sm-3">
                    <button class="form-control" type="button" id="unsharp" class="btn btn-primary">Unsharp</button>
                </div>
            </div>
        </form>
    </div>
    <br>
    <div class="row">
        <div class="col-md-6">
            <div style="width:512px;height:512px;position:relative;color: white;display:inline-block;border-style:solid;border-color:black;"
                 oncontextmenu="return false"
                 class='disable-selection noIbar'
                 unselectable='on'
                 onselectstart='return false;'
                 onmousedown='return false;'>
                <div id="dicomImage"
                     style="width:512px;height:512px;top:0px;left:0px; position:absolute">
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <span>Max Web Workers: </span><span id="maxWebWorkers"></span><br>
            <span>Num Web Workers: </span><span id="numWebWorkers"></span><br>
            <span>Num Queued Tasks: </span><span id="numQueuedTasks"></span><br>
            <span>Num Tasks Executing: </span><span id="numTasksExecuting"></span><br>
            <span>Total Tasks Executed: </span><span id="totalTasksExecuted"></span><br>
            <span>Total Task Execution Time: </span><span id="totalTaskExecutionTime"></span><br>
            <span>Total Task Delay Time: </span><span id="totalTaskDelayTime"></span><br>
        </div>
    </div>
</div>
</body>

<!-- include the cornerstone library -->
<script src="../cornerstone.min.js"></script>
<SCRIPT src="../cornerstoneMath.min.js"></SCRIPT>
<SCRIPT src="../cornerstoneTools.min.js"></SCRIPT>

<!-- include the dicomParser library as the WADO image loader depends on it -->
<script src="../dicomParser.min.js"></script>

<!-- include the cornerstoneWADOImageLoader library -->
<script src="../../dist/cornerstoneWADOImageLoader.js"></script>

<!-- Lines ONLY required for this example to run without building the project -->
<script>window.cornerstoneWADOImageLoader || document.write('<script src="https://unpkg.com/cornerstone-wado-image-loader">\x3C/script>')</script>
<script src="../utils/customWebWorkersConfig.js"></script>

<script>
    // Initialize the web worker manager with our custom web worker task
    // window.customWebWorkerConfig contains custom web worker config and a fallback in case there is no dist folder
    config = window.customWebWorkerConfig;

    cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
    cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
    document.getElementById('numWebWorkers').textContent = config.maxWebWorkers;

    let loaded = false;
    let loadedImage;

    function loadAndViewImage(imageId) {
        const element = document.getElementById('dicomImage');
        try {
            const start = new Date().getTime();
            cornerstone.loadAndCacheImage(imageId, {usePDFJS: false}).then(function(image) {
                console.log(image);
                loadedImage = image;
                updateStatistics();
                const viewport = cornerstone.getDefaultViewportForImage(element, image);
                cornerstone.displayImage(element, image, viewport);
                if(loaded === false) {
                    cornerstoneTools.mouseInput.enable(element);
                    cornerstoneTools.mouseWheelInput.enable(element);
                    cornerstoneTools.wwwc.activate(element, 1); // ww/wc is the default tool for left mouse button
                    cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
                    cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
                    cornerstoneTools.zoomWheel.activate(element); // zoom is the default tool for middle mouse wheel
                    loaded = true;
                }

            }, function(err) {
                alert(err);
            });
        }
        catch(err) {
            alert(err);
        }
    }

    function downloadAndView(){
        let url = document.getElementById('wadoURL').value;

        // prefix the url with wadouri: so cornerstone can find the image loader
        url = "wadouri:" + url;

        // image enable the dicomImage element and activate a few tools
        loadAndViewImage(url);
    }

    function getUrlWithoutFrame() {
        const url = document.getElementById('wadoURL').value;
        const frameIndex = url.indexOf('frame=');
        if(frameIndex !== -1) {
            url = url.substr(0, frameIndex-1);
        }
        return url;
    }

    function updateStatistics() {
        var stats = cornerstoneWADOImageLoader.webWorkerManager.getStatistics();
        document.getElementById('maxWebWorkers').textContent = stats.maxWebWorkers;
        document.getElementById('numWebWorkers').textContent = stats.numWebWorkers;
        document.getElementById('numQueuedTasks').textContent = stats.numTasksQueued;
        document.getElementById('numTasksExecuting').textContent = stats.numTasksExecuting;
        document.getElementById('totalTasksExecuted').textContent = stats.numTasksCompleted;
        document.getElementById('totalTaskExecutionTime').textContent = stats.totalTaskTimeInMS;
        document.getElementById('totalTaskDelayTime').textContent = stats.totalTimeDelayedInMS;
    }

    var sleepTaskLoaded = false;

    function startWebWorker() {
        // dyanmically load the sleep task
        if(!sleepTaskLoaded) {
            sleepTaskLoaded = true;
            // TODO: This URL probably won't work on hosted site
            cornerstoneWADOImageLoader.webWorkerManager.loadWebWorkerTask(
              `${window.location.protocol}//${window.location.host}/examples/customWebWorkerTask/sleepTask.js`,{
                        'sleepTask' : {
                            sleepTime: 3000
                        }
                    }
            );
        }

        const task = cornerstoneWADOImageLoader.webWorkerManager.addTask('sleepTask', {},-10);
        const promise = task.promise;
        promise.then(function(result) {
            console.log('sleep task completed');
            updateStatistics();
        });
        updateStatistics();
    }

    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    document.getElementById('downloadAndView').addEventListener('click', function(e) {
        downloadAndView();
    });
    document.getElementById('startWebWorker').addEventListener('click', function(e) {
        startWebWorker();
    });
    document.getElementById('start10WebWorkers').addEventListener('click', function(e) {
        for(let i=0; i < 10; i++) {
            startWebWorker();
        }
    });



    function convolute(kernel, multiplier, calculateWWWC) {
        const promise = cornerstoneWADOImageLoader.webWorkerManager.addTask('convolveTask', {
            pixelData :loadedImage.getPixelData(),
            kernel : kernel,
            multiplier: multiplier,
            imageFrame: {
                typedArrayName: loadedImage.getPixelData().constructor.name,
                width : loadedImage.width,
                height : loadedImage.height
            }
        }, -8).promise;
        promise.then(function(result) {
            console.log('convolveTask task completed');
            result.pixelData = new Int16Array(result.pixelData);

            const sharpenedImage = {
                color: false,
                columns: loadedImage.columns,
                rows: loadedImage.rows,
                width: loadedImage.width,
                height: loadedImage.height,
                imageId: new Date().toISOString(),
                maxPixelValue: result.minMax.max,
                minPixelValue: result.minMax.min,
                windowWidth: calculateWWWC ? (result.minMax.max - result.minMax.max) : loadedImage.windowWidth,
                windowLevel: calculateWWWC ? ((result.minMax.max + result.minMax.max) / 2) : loadedImage.windowLevel,
                sizeInBytes: loadedImage.sizeInBytes,
                render: loadedImage.render,
                slope: loadedImage.slope,
                intercept: loadedImage.intercept,
                invert: loadedImage.invert,
                getPixelData: function () {
                    return result.pixelData;
                }
            };

            cornerstone.displayImage(element, sharpenedImage);
            loadedImage = sharpenedImage;
            updateStatistics();
        });
    }

    document.getElementById('sharpen').addEventListener('click', function(e) {
        convolute([
            [ 0,-1, 0],
            [-1, 5,-1],
            [ 0,-1, 0]
        ], 1);
    });
    document.getElementById('edgeDetect').addEventListener('click', function(e) {
        convolute([
            [-1,-1,-1],
            [-1, 9,-1],
            [-1,-1,-1]
        ], 1);
    });
    document.getElementById('boxBlur').addEventListener('click', function(e) {
        convolute([
            [1,1,1],
            [1,1,1],
            [1,1,1]
        ], 1/9);
    });
    document.getElementById('gaussianBlur').addEventListener('click', function(e) {
        convolute([
            [1,2,1],
            [2,4,2],
            [1,2,1]
        ], 1/16);
    });
    document.getElementById('emboss').addEventListener('click', function(e) {
        convolute([
            [-2,1,0],
            [-1,1,1],
            [ 0,1,2]
        ], 1/3);
    });

    document.getElementById('unsharp').addEventListener('click', function(e) {
        convolute([
            [ 1, 4,   6, 4, 1],
            [ 4,16,  24,16, 4],
            [ 6,24,-476,24, 6],
            [ 4,16,  24,16, 4],
            [ 1, 4,   6, 4, 1],
        ], -1/256);
    });

    const form = document.getElementById('form');
    form.addEventListener('submit', function() {
        downloadAndView();
        return false;
    });

    document.getElementById('toggleCollapseInfo').addEventListener('click', function() {
        if (document.getElementById('collapseInfo').style.display === 'none') {
            document.getElementById('collapseInfo').style.display = 'block';
        } else {
            document.getElementById('collapseInfo').style.display = 'none';
        }
    });

    // set an interval timer to periodically update the statistics for a real time view of
    // what the web workers are doing
    setInterval(function() {
        updateStatistics();
    }, 100);
</script>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值