javascriptreactjscornerstonejs

How to reset the cornerstone viewport when new image is loaded


I am trying to make a Dicom viewer app in react using Cornerstone.js library. I have two components in my react app. One is ImagePreview and the other is CornerStoneElement. CornerStoneElement is where I initialize the cornerstone library and it loads the current image in its state. When a new image is pushed to CornerStoneElement's state it is loading the new image in a weird way as all the aspect ratios are gone and the viewport is zoomed in. Upon switching the image multiple times through ImagePreview, the viewport keeps getting bigger and bigger. What I need is to reset the viewport whenever a new image is loaded in the CornerStoneElement component. Here is the code for both components.

ImagePreview.js

import React,{useState,useEffect,useRef} from 'react'

const ImagePreview = ({ image,parentStateSetter,imageListIndex }) => {

let setParentState = (e) => {    
parentStateSetter(e.target.getAttribute('image-list-index'));
    
 }


return (
  <div className="py-5 px-10">
    <img src={image.previewURL} className="w-full" onClick={setParentState} image-list-index= {imageListIndex}/>
    
  </div>
   );
}

export default ImagePreview

CornerStoneElement.js

import React,{useState, setState, useRef, useEffect} from "react";
import * as cornerstone from "cornerstone-core";
import * as cornerstoneMath from "cornerstone-math";
import * as cornerstoneTools from "cornerstone-tools";

import Hammer from "hammerjs";
import * as cornerstoneWebImageLoader from "cornerstone-web-image-loader";

cornerstoneTools.external.cornerstone = cornerstone;
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
cornerstoneWebImageLoader.external.cornerstone = cornerstone;
cornerstoneTools.external.Hammer = Hammer;

cornerstoneTools.init();

const CornerStoneElement = (props) => {

    console.log('props is called', props);
    const stack = (Object.keys(props.stack).length > 0 )? props.stack : '';
    const [viewport, setViewport] = useState(cornerstone.getDefaultViewport(null, undefined));
    const imageId  = (Object.keys(props.stack).length > 0 )? props.stack.imageIds[0] : '';;
    const viewPortRef = useRef(null);

    const onWindowResize = () => {
        console.log("onWindowResize :", viewPortRef.current);
        cornerstone.resize(viewPortRef.current);
    }
    
    const onImageRendered = () => {
        const viewport = cornerstone.getViewport(viewPortRef.current);
        console.log('onImageRendered :',viewport);
        setViewport(viewport);       
        
    }
    
    const onNewImage = () => {
        const enabledElement = cornerstone.getEnabledElement(viewPortRef.current);
        
       
    }

    const addZoomTool = (e) => {
      e.preventDefault();
      const ZoomMouseWheelTool = cornerstoneTools.ZoomMouseWheelTool;

      cornerstoneTools.addTool(ZoomMouseWheelTool)
      cornerstoneTools.setToolActive('ZoomMouseWheel', { mouseButtonMask: 1 })
    }

    const addLengthTool = (e) => {
      e.preventDefault();
      const LengthTool = cornerstoneTools.LengthTool;

      cornerstoneTools.addTool(LengthTool)
      cornerstoneTools.setToolActive('Length', { mouseButtonMask: 1 });
    }

    const addElipticalTool = (e) => {
      e.preventDefault();
      const EllipticalRoiTool = cornerstoneTools.EllipticalRoiTool;

      cornerstoneTools.addTool(EllipticalRoiTool)
      cornerstoneTools.setToolActive('EllipticalRoi', { mouseButtonMask: 1 })
    }

    useEffect(() => {

        console.log('use effect is called ');
        
        const element = viewPortRef.current;        
        // Enable the DOM Element for use with Cornerstone
        
        cornerstone.enable(element);
    
        // Load the first image in the stack
        if(imageId){

          cornerstone.loadImage(imageId).then(image => {
            // Display the first image    

            
            cornerstone.displayImage(element, image);
            // Add the stack tool state to the enabled element
            /* cornerstoneTools.addStackStateManager(element, ["stack"]);
            cornerstoneTools.addToolState(element, "stack", stack);    */ 
               
            element.addEventListener( "cornerstoneimagerendered", onImageRendered );
            element.addEventListener("cornerstonenewimage", onNewImage);
            window.addEventListener("resize",onWindowResize); 
          });
          console.log('inside comp will mount :', element);
        }
        
      
    }, [imageId])

    return (
        <div className= "py-5 px-10 ">
          <div className="inline-flex">
            <button className = "text-sm bg-blue-500 hover:bg-blue-700 text-white  p-2 rounded m-2" onClick = {addZoomTool}> Zoom Tool</button>
            <button className = "text-sm bg-blue-500 hover:bg-blue-700 text-white  p-2  rounded m-2" onClick = {addLengthTool}> Length Tool </button>
            <button className = "text-sm bg-blue-500 hover:bg-blue-700 text-white  p-2 rounded m-2" onClick = {addElipticalTool}> Eliptical Tool </button>
          </div>
          
          <div
            className="viewportElement my-3"           
            ref={viewPortRef}
          >
            <canvas className="cornerstone-canvas" />
            <div>Zoom: {viewport.scale}</div>
            <div>
              WW/WC: {viewport.voi.windowWidth} /{" "}
              {viewport.voi.windowCenter}
            </div>
          </div>
        </div>
      );
}

export default CornerStoneElement;

Solution

  • So the problem was not in cornerstone. All I had to do is assign height to the parent of cornerstone element inside of which it was getting rendered and it solved the issue.