Dynamic multiple images.

1,547 views
Skip to first unread message

codef...@gmail.com

unread,
Jul 23, 2015, 2:03:16 AM7/23/15
to cornerstone platform
Hello everyone,

  I am making a multiple image UI for medical imaging using conerstone library, But there is a problem with dynamic image ids, I have used array with multiple image but when it load in DOM it's give me "loadAndCacheImage: no image loader for imageId". HERE is my code for multiple image.

$(document).ready(function() {
            var imageIds = ["https://vna.hackathon.siim.org/dcm4chee-arc/wado/DCM4CHEE?requestType=WADO&studyUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.988079582344471175076015633105&seriesUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.227571573286142502566010959726&objectUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.309859580039258764624742918740&contentType=application%2Fdicom", "https://vna.hackathon.siim.org/dcm4chee-arc/wado/DCM4CHEE?requestType=WADO&studyUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.988079582344471175076015633105&seriesUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.227571573286142502566010959726&objectUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.309859580039258764624742918740&contentType=application%2Fdicom", "https://vna.hackathon.siim.org/dcm4chee-arc/wado/DCM4CHEE?requestType=WADO&studyUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.988079582344471175076015633105&seriesUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.227571573286142502566010959726&objectUID=1.3.6.1.4.1.14519.5.2.1.7777.9002.309859580039258764624742918740&contentType=application%2Fdicom"];

                
                var currentImageIndex = 0;
                
                // updates the image display
                function updateTheImage(imageIndex) {
                    return cornerstone.loadAndCacheImage(imageIds[imageIndex]).then(function(image) {
                        currentImageIndex = imageIndex;
                        var currentValueSpan = document.getElementById("sliceText");
                currentValueSpan.textContent = "Image " + (currentImageIndex + 1) + "/" + imageIds.length;
                        var viewport = cornerstone.getViewport(element);
                        cornerstone.displayImage(element, image, viewport);
                    });
                }
                // image enable the element
                var element = $('#dicomImage').get(0);
                cornerstone.enable(element);
                // set event handlers
            
                // setup handlers before we display the image
                $(element).on("CornerstoneImageRendered", onImageRendered);
                // load and display the image
                var imagePromise = updateTheImage(0);
                // add handlers for mouse events once the image is loaded.
                imagePromise.then(function() {
                    viewport = cornerstone.getViewport(element);
                    $('#bottomright').text("Zoom: " + viewport.scale.toFixed(2) + "x");
                    $('#bottomleft').text("WW/WC:" + Math.round(viewport.voi.windowWidth) + "/" + Math.round(viewport.voi.windowCenter));
                    
                    // add event handlers to pan image on mouse move
                    $('#dicomImage').mousedown(function (e) {
                        var lastX = e.pageX;
                        var lastY = e.pageY;
                        var mouseButton = e.which;
                        $(document).mousemove(function (e) {
                            var deltaX = e.pageX - lastX,
                                    deltaY = e.pageY - lastY;
                            lastX = e.pageX;
                            lastY = e.pageY;
                            if (mouseButton == 1) {
                                var viewport = cornerstone.getViewport(element);
                                viewport.voi.windowWidth += (deltaX / viewport.scale);
                                viewport.voi.windowCenter += (deltaY / viewport.scale);
                                cornerstone.setViewport(element, viewport);
                                $('#bottomleft').text("WW/WL:" + Math.round(viewport.voi.windowWidth) + "/" + Math.round(viewport.voi.windowCenter));
                            }
                            else if (mouseButton == 2) {
                                var viewport = cornerstone.getViewport(element);
                                viewport.translation.x += (deltaX / viewport.scale);
                                viewport.translation.y += (deltaY / viewport.scale);
                                cornerstone.setViewport(element, viewport);
                            }
                            else if (mouseButton == 3) {
                                var viewport = cornerstone.getViewport(element);
                                viewport.scale += (deltaY / 100);
                                cornerstone.setViewport(element, viewport);
                                $('#bottomright').text("Zoom: " + viewport.scale.toFixed(2) + "x");
                            }
                        });
                        $(document).mouseup(function (e) {
                            $(document).unbind('mousemove');
                            $(document).unbind('mouseup');
                        });
                    });
                    
                    $('#dicomImage').on('mousewheel DOMMouseScroll', function (e) {
                        // Firefox e.originalEvent.detail > 0 scroll back, < 0 scroll forward
                        // chrome/safari e.originalEvent.wheelDelta < 0 scroll back, > 0 scroll forward
                        if (e.originalEvent.wheelDelta < 0 || e.originalEvent.detail > 0) {
                            if (currentImageIndex == 0) {
                                updateTheImage(1);
                            }
                        } else {
                            if (currentImageIndex == 1) {
                                updateTheImage(0);
                            }
                        }
                        //prevent page fom scrolling
                        return false;
                    });
                });
            });
And in my ui

<div id="dicomImageWrapper" style="width:512px;height:512px;position:relative;color: white;"
        class="cornerstone-enabled-image"
        oncontextmenu="return false"
        unselectable='on'
        onselectstart='return false;'
        onmousedown='return false;'>
       <div id="dicomImage" oncontextmenu="return false" style="width:512px;height:512px;top:0px;left:0px; position:absolute">
       </div>
        
       <div id="topleft" style="position: absolute;top:0px; left:0px">
           Patient Name
       </div>
       <div id="topright" style="position: absolute;top:0px; right:0px">
           Render Time:
       </div>
       <!-- <div id="bottomleft" style="position: absolute;bottom:0px; left:0px">
           WW/WC:
       </div> -->
<div id="sliceText" style="position: absolute;bottom:0px; left:0px">
           Image:
       </div>
    </div>

       <script type="text/javascript" src="bower_components/cornerstone/dist/cornerstone.js"></script>
<script type="text/javascript" src="bower_components/image-jpeg2000/dist/jpx.js"></script>
<script type="text/javascript" src="bower_components/cornerstoneMath/dist/cornerstoneMath.js"></script>
<script type="text/javascript" src="src/medical-files/cornerstoneTools.js"></script>
<script type="text/javascript" src="bower_components/dicomParser/dist/dicomParser.js"></script>
<script type="text/javascript" src="bower_components/cornerstoneWADOImageLoader/dist/cornerstoneWADOImageLoader.js"></script>
  

codef...@gmail.com

unread,
Jul 23, 2015, 2:47:58 AM7/23/15
to cornerstone platform, codef...@gmail.com
http://chafey.github.io/cornerstoneTools/examples/stackScroll/index.html  Also see this one but not wrok ffor dynamic images

Erik Ziegler

unread,
Jul 23, 2015, 3:34:38 AM7/23/15
to cornerstone platform, codef...@gmail.com
You'll have to be more clear about what you mean by "dynamic". Do you mean that the URL will stay the same but the data behind it will change? In that case you'd need to rerun loadAndCacheImage on a timer or something, since cornerstone has no mechanism for that.

The error you are seeing has nothing to do with whether the URL is dynamic or not. Image loaders in cornerstone are defined and selected by their prefix. In your previous post you already had the URL correct. You must prefix it with "dicomweb:". Check the imageId you used in your previous post.

codef...@gmail.com

unread,
Jul 23, 2015, 3:39:45 AM7/23/15
to cornerstone platform, er...@prevuemedical.com
I have array with multiple images and i want when user scrool up and down then i want to change the .dic image.Then i have to do something like this


            // updates the image display
            function updateTheImage(imageIndex) {
           
                return cornerstone.loadAndCacheImage(imageIds[imageIndex]).then(function(image) {
                    currentImageIndex = imageIndex;
                    var currentValueSpan = document.getElementById("sliceText");
            currentValueSpan.textContent = "Image " + (currentImageIndex + 1) + "/" + imageIds.length;
                    var viewport = cornerstone.getViewport(element);
                    cornerstone.displayImage(element, image, viewport);
                });
            }

something like this.
Message has been deleted

Erik Ziegler

unread,
Jul 23, 2015, 3:58:16 AM7/23/15
to cornerstone platform, codef...@gmail.com
Read the examples carefully, they show you exactly how to do what you are asking.  See:


A few more things:

- There are mouseWheel, mouseDrag, touchDrag, and keyboard scroll tools already implemented, so you can probably use one of those instead of writing your own.
- All of your image Ids need to have the proper prefix or they will not load.
- There is a helper function for manually "scrolling" to an image index, which is what it seems you are trying to do (https://github.com/chafey/cornerstoneTools/blob/master/src/util/scrollToIndex.js). It would work something like

var index = 1; // or whichever index in the stack you want
cornerstoneTools.scrollToIndex(element, index);

- You can get the current index from the object returned by calling getToolState with the element and toolType "stack"
- You can attach a callback to run when new images are displayed. This is exactly what is done in the example above (using 
jQuery's "on" function $(element).on("CornerstoneNewImage", onNewImage);). You should use this callback to update any text boxes or whatever you want to change. This is also done in the stackScroll example.
Message has been deleted

codef...@gmail.com

unread,
Jul 23, 2015, 5:02:56 AM7/23/15
to cornerstone platform, er...@prevuemedical.com
But i don't want to load image from this <script src="../exampleImageLoader.js"></script> . I have array of image.
Trying your example. if works then great

Erik Ziegler

unread,
Jul 23, 2015, 5:08:29 AM7/23/15
to cornerstone platform, codef...@gmail.com
You should absolutely not be using the example image loader at all. The example image loader is *only* for the live examples so we don't have to have a server to host the example data.

For real DICOM data use the cornerstoneWADOImageLoader (https://github.com/chafey/cornerstoneWADOImageLoader) or for JPEG or other Web images use the Web Image Loader (https://github.com/chafey/cornerstoneWebImageLoader).

codef...@gmail.com

unread,
Jul 23, 2015, 5:23:57 AM7/23/15
to cornerstone platform, er...@prevuemedical.com
Common please tell which link i have to follow, I follow the both link but no one  work for me  , Please listen my question carefully Erik Ziegler look i have array of image, i want to show the image in ui then if user scroll up and down then i have to change the image (next and previous). Only this is i want no please help me. Here is my code for loading images and change image at scroll

var currentImageIndex = 0;

        // updates the image display
            function updateTheImage(imageIndex) {
            return cornerstone.loadAndCacheImage(arr[imageIndex]).then(function(image) {
                    currentImageIndex = imageIndex;
                    console.log(currentImageIndex)
                });
            }
            
        var element = $('#myImage').get(0);
  var imageId = "dicomweb:"+arr[currentImageIndex];
 
  cornerstone.enable(element);
 
  $('#myImage').on('mousewheel DOMMouseScroll', function (e) {
 
  if (e.originalEvent.wheelDelta < 0 || e.originalEvent.detail > 0) {
                    if (currentImageIndex == 0) {
                        updateTheImage(1);
                    }
                } else {
                    if (currentImageIndex == 1) {
                        updateTheImage(0);
                    }
                }
                //prevent page fom scrolling
                return false;
            });

  cornerstone.loadImage(imageId).then(function(image) {
  cornerstoneTools.mouseInput.enable(element);
    cornerstoneTools.mouseWheelInput.enable(element);
    cornerstone.displayImage(element, image);
    cornerstoneTools.wwwc.activate(element, 1);
    cornerstoneTools.pan.activate(element, 2); 
    cornerstoneTools.zoom.activate(element, 4); 
    cornerstoneTools.zoomWheel.activate(element); 
  });  

Erik Ziegler

unread,
Jul 23, 2015, 5:35:58 AM7/23/15
to cornerstone platform, codef...@gmail.com
It's really very simple and you are somehow managing to make it unnecessarily complicated.

Instead of the exampleImageLoader, download cornerstoneWADOImageLoader and include that in your page:

<script src="cornerstoneWADOImageLoader.js"></script>

Then, in your javascript, do this:

    var element = $('#dicomImage').get(0);

    function onNewImage(e, data) {
        var newImageIdIndex = stack.currentImageIdIndex;

        // Populate the current slice span
        var currentValueSpan = document.getElementById("sliceText");
        currentValueSpan.textContent = "Image " + (newImageIdIndex + 1) + "/" + imageIds.length;
    }
    $(element).on("CornerstoneNewImage", onNewImage);

    var imageIds = [
    ];

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


    // Enable the dicomImage element and the mouse inputs
    cornerstone.enable(element);
    cornerstoneTools.mouseInput.enable(element);
    cornerstoneTools.mouseWheelInput.enable(element);
    cornerstone.loadImage(imageIds[0]).then(function(image) {
        // Display the image
        cornerstone.displayImage(element, image);

        // Set the stack as tool state
        cornerstoneTools.addStackStateManager(element, ['stack']);
        cornerstoneTools.addToolState(element, 'stack', stack);

        // Enable all tools we want to use with this element
        cornerstoneTools.wwwc.activate(element, 1);
        cornerstoneTools.stackScrollWheel.activate(element);
    });

Make sure the two images in your array are actually different or you won't see a difference apart from the image number.

codef...@gmail.com

unread,
Jul 23, 2015, 5:56:23 AM7/23/15
to cornerstone platform, er...@prevuemedical.com
Trying your one and it's work with error "Uncaught image has not been loaded yet" 
Thanks Erik

Erik Ziegler

unread,
Jul 23, 2015, 6:16:44 AM7/23/15
to cornerstone platform, codef...@gmail.com
You are doing something wrong. I just tested it and it works fine.

The exact code of the entire page was as follows:

<!DOCTYPE HTML>
<html>
<head>
    <!-- support for mobile touch devices -->
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">

    <!-- twitter bootstrap CSS stylesheet - not required by cornerstoneTools -->

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

</head>
<body>
<div class="container">
    <div class="page-header">
        <h1>
            Stack Scroll Tools Example
        </h1>
        <p>
            This page contains an example of the stackScroll tool, the play/stopClip tools, and integration with an HTML5 "range" input.
            Scroll by left click dragging or using the mouse wheel
        </p>
        <a href="../index.html">Go back to the Examples page</a>
    </div>

    <div class="row">
        <div class="col-xs-2">
            <ul class="list-group">
                <a href="#" id="playClip" class="list-group-item">Play Clip</a>
                <a href="#" id="stopClip" class="list-group-item">Stop Clip</a>
            </ul>
            <label>Loop</label>
            <input type="checkbox" id="loop" checked />
            <input type="range" id="slice-range">
        </div>
        <div class="col-xs-6">
            <div style="width:512px;height:512px;position:relative;display:inline-block;color:white;"
                 oncontextmenu="return false"
                 class='cornerstone-enabled-image'
                 unselectable='on'
                 onselectstart='return false;'
                 onmousedown='return false;'>
                <div id="dicomImage"
                     style="width:512px;height:512px;top:0px;left:0px; position:absolute;">
                </div>
                <div id="mrtopleft" style="position: absolute;top:3px; left:3px">
                    Patient Name
                </div>
                <div id="mrtopright" style="position: absolute;top:3px; right:3px">
                    Hospital
                </div>
                <div id="mrbottomright" style="position: absolute;bottom:6px; right:3px">
                    <div id="frameRate"></div>
                    <div id="zoomText">Zoom: </div>
                    <div id="sliceText">Image: </div>
                </div>
                <div id="mrbottomleft" style="position: absolute;bottom:3px; left:3px">
                    WW/WC:
                </div>
            </div>
        </div>

    </div>

</body>

<!-- jquery - included to make things easier to demo, not needed or used by the cornerstone library but
is used by our example image loader-->
<script src="../jquery.min.js"></script>

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

<!-- include the cornerstone tools library -->
<script src="../../dist/cornerstoneTools.js"></script>

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

<script>
</script>
</html>

I saved this as cornerstoneTools/examples/test/index.html and ran it by serving the page with python -m SimpleHTTPServer from the cornerstoneTools directory, and accessing http://127.0.0.1:8000/examples/test/index.html.
...

codef...@gmail.com

unread,
Jul 23, 2015, 6:29:28 AM7/23/15
to cornerstone platform, er...@prevuemedical.com
Thank you so much Erik, may it's my mistake but really thanks for your help now i am working on thumbnail for showing image on left side
...

codef...@gmail.com

unread,
Jul 24, 2015, 10:54:09 AM7/24/15
to cornerstone platform, er...@prevuemedical.com, codef...@gmail.com
For multiple image stack scroll work but can i use previous and next button to display image in ui.
...

codef...@gmail.com

unread,
Jul 24, 2015, 11:15:26 AM7/24/15
to cornerstone platform, er...@prevuemedical.com, codef...@gmail.com
Trying to call the cornerstoneTools.stackScrollWheel.activate(element);  in button click but it's not work because this api work only for scroll movement  so is there any way to call the next previous image in button

Erik Ziegler

unread,
Jul 24, 2015, 3:08:28 PM7/24/15
to cornerstone platform, codef...@gmail.com
I already answered this question about 5 posts ago. Here it is copy/pasted again:

- There is a helper function for manually "scrolling" to an image index, which is what it seems you are trying to do (https://github.com/chafey/cornerstoneTools/blob/master/src/util/scrollToIndex.js). It would work something like

var index = 1; // or whichever index in the stack you want
cornerstoneTools.scrollToIndex(element, index);

- You can get the current index from the object returned by calling getToolState with the element and toolType "stack"
- You can attach a callback to run when new images are displayed. This is exactly what is done in the example above (using 
jQuery's "on" function $(element).on("CornerstoneNewImage", onNewImage);). You should use this callback to update any text boxes or whatever you want to change. This is also done in the stackScroll example.

codef...@gmail.com

unread,
Jul 25, 2015, 5:30:06 AM7/25/15
to cornerstone platform, er...@prevuemedical.com
Hi Erik,  Thank you so much for reply.
I tried and it's work .

here is my code 

     $('#zoomIn').click(function (e) {
           
            var stackData = cornerstoneTools.getToolState(element, 'stack');
            stackData = stackData.data[0];
            var newImageIdIndex = stack.currentImageIdIndex + 1;
            if(newImageIdIndex !== stackData.currentImageIdIndex && stackData.imageIds[newImageIdIndex] !== undefined) {
                    cornerstone.loadAndCacheImage(stackData.imageIds[newImageIdIndex]).then(function(image) {
                   var viewport = cornerstone.getViewport(element);
                   stackData.currentImageIdIndex = newImageIdIndex;

                   var currentValueSpan = document.getElementById("sliceText");
                   currentValueSpan.textContent = "Image " + (stackData.currentImageIdIndex + 1) + "/" + imageIds.length;
                   cornerstone.displayImage(element, image, viewport);
            });
                }
            });
            
       $('#zoomOut').click(function (e) {
       
        var stackData = cornerstoneTools.getToolState(element, 'stack');
        stackData = stackData.data[0];
        var newImageIdIndex = stack.currentImageIdIndex - 1;
        if(newImageIdIndex !== stackData.currentImageIdIndex && stackData.imageIds[newImageIdIndex] !== undefined) {
               cornerstone.loadAndCacheImage(stackData.imageIds[newImageIdIndex]).then(function(image) {
                   var viewport = cornerstone.getViewport(element);
                   stackData.currentImageIdIndex = newImageIdIndex;

                   var currentValueSpan = document.getElementById("sliceText");
                   currentValueSpan.textContent = "Image " + (stackData.currentImageIdIndex + 1) + "/" + imageIds.length;
                   cornerstone.displayImage(element, image, viewport);
                   
                });
           }
       });
...
Reply all
Reply to author
Forward
0 new messages