Using cornerstone3D in React with Vite - cannot get image to display

254 views Asked by At

I'm having trouble getting the cornerstone3d Render Stack of Images tutorial working with React and Vite.

For the registerWebImageLoader function I'm using the example found here which is referred to in the cornerstone (legacy) Image Loader.

It appears a viewport-element and cornerstone-canvas are being added to the DOM, but the canvas is all black and no image is shown.

The only error I'm seeing in the console is:

init.ts:123 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'tier') at init (init.ts:123:24) at async App.tsx:29:36

Here's my code:

import React, { useEffect, useRef } from "react";

import {
  Enums,
  RenderingEngine,
  imageLoader,
  init,
} from "@cornerstonejs/core";

import registerWebImageLoader from "./utils/registerWebImageLoader";

const renderingEngineId = "myRenderingEngine";
const viewportId = "myViewport";
const imageIds = [
  "web:https://cs3d-jpg-example.s3.us-east-2.amazonaws.com/a_vm1460.png",
];

const { ViewportType } = Enums;

registerWebImageLoader(imageLoader);

export default function App() {
  const [isInitialized, setIsInitialized] = React.useState(false);

  const wrapperRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    (async () => {
      const initializationResult = await init();
      setIsInitialized(initializationResult);
    })();
  }, []);

  useEffect(() => {
    if (!isInitialized) return;

    const wrapper = wrapperRef?.current;

    if (!wrapper) return;

    const renderingEngine = new RenderingEngine(renderingEngineId);

    renderingEngine.enableElement({
      viewportId,
      element: wrapper,
      type: ViewportType.STACK,
    });

    const viewport = renderingEngine.getViewport(viewportId);

    viewport.setStack(imageIds, 0);

    viewport.render();
  }, [isInitialized]);

  return (
    <div
      id={viewportId}
      ref={wrapperRef}
      style={{
        height: "500px",
        width: "500px",
      }}
    />
  );
}

I also tried getting the example found here to work, but did not have any luck with that, either. Same black box and no images displayed.

1

There are 1 answers

0
Andy On

Got this sorted out - turns out you need to do quite a bit more initialization than just the initialization for @cornerstonejs/core.

import { useEffect, useRef } from "react";

import {
  Enums,
  RenderingEngine,
  imageLoader,
  metaData,
  volumeLoader,
} from "@cornerstonejs/core";

import { hardcodedMetaDataProvider } from "./utils/hardcodedMetaDataProvider";
import { initDemo } from "./utils/initDemo";
import { registerWebImageLoader } from "./utils/registerWebImageLoader";

const imageIds = ["web:https://picsum.photos/500"];
const renderingEngineId = "myRenderingEngine";
const viewportId = "myViewport";
const volumeId = "myVolume";

registerWebImageLoader(imageLoader);

metaData.addProvider(
  (type, imageId) => hardcodedMetaDataProvider(type, imageId, imageIds),
  10000
);

/** 
 * @description Basic working example of cornerstone3D with React using a stripped down version of the webLoader example linked below. Their initDemo function seemed to be the key to getting this working.
 * @link https://github.com/cornerstonejs/cornerstone3D/blob/main/packages/core/examples/webLoader/index.ts
 * @link https://github.com/cornerstonejs/cornerstone3D/blob/main/utils/demo/helpers/initDemo.js
 */
async function run(container: HTMLDivElement) {
  try {
    const { initializationResult } = await initDemo();

    if (!initializationResult) throw new Error("Initialization failed");

    const renderingEngine = new RenderingEngine(renderingEngineId);

    const volume = await volumeLoader.createAndCacheVolume(volumeId, { imageIds });

    renderingEngine.setViewports([
      {
        element: container,
        type: Enums.ViewportType.STACK,
        viewportId: viewportId,
      },
    ]);

    const viewport = renderingEngine.getStackViewports()[0];

    volume.load();

    await viewport.setStack(imageIds);

    await viewport.setImageIdIndex(0);

    renderingEngine.render();
  } catch (error) {
    console.error(error);
  }
}

export default function App() {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const container = containerRef.current;

    if (!container) return;

    run(container);
  }, []);

  return (
    <div
      id={viewportId}
      ref={containerRef}
      style={{
        height: "500px",
        width: "500px",
      }}
    />
  );
}