Skip to content

Instantly share code, notes, and snippets.

@AlexMold
Last active November 13, 2024 18:33
Show Gist options
  • Save AlexMold/ad292158b27a35c04be93a9a1548cffc to your computer and use it in GitHub Desktop.
Save AlexMold/ad292158b27a35c04be93a9a1548cffc to your computer and use it in GitHub Desktop.
react dicom render
import type { Types } from "@cornerstonejs/core";
import { RenderingEngine, Enums, setVolumesForViewports, volumeLoader} from "@cornerstonejs/core";
import * as cornerstoneTools from "@cornerstonejs/tools";
import initDemo from "./initDemo";
const { PanTool, WindowLevelTool, StackScrollTool, ZoomTool, ToolGroupManager, Enums: csToolsEnums } = cornerstoneTools;
const { MouseBindings } = csToolsEnums;
const { ViewportType } = Enums;
const toolGroupId = 'myToolGroup';
const volumeName = "CT_VOLUME_ID"; // Id of the volume less loader prefix
const volumeLoaderScheme = "cornerstoneStreamingImageVolume"; // Loader id which defines which volume loader to use
const volumeId = `${volumeLoaderScheme}:${volumeName}`; // VolumeId with loader id + volume id
const viewportIds = [
'CT_SAGITTAL_STACK_1',
'CT_SAGITTAL_STACK_2',
'CT_SAGITTAL_STACK_3',
];
export async function run(element1: HTMLDivElement, element2: HTMLDivElement, element3: HTMLDivElement) {
// Init Cornerstone and related libraries
await initDemo();
cornerstoneTools.addTool(PanTool);
cornerstoneTools.addTool(WindowLevelTool);
cornerstoneTools.addTool(StackScrollTool);
cornerstoneTools.addTool(ZoomTool);
// Define a tool group, which defines how mouse events map to tool commands for
// Any viewport using the group
const toolGroup = ToolGroupManager.createToolGroup(toolGroupId);
if (!toolGroup) {
throw new Error("ToolGroup not found");
}
// Add tools to the tool group
toolGroup.addTool(WindowLevelTool.toolName);
toolGroup.addTool(PanTool.toolName);
toolGroup.addTool(ZoomTool.toolName);
toolGroup.addTool(StackScrollTool.toolName);
// Set the initial state of the tools, here all tools are active and bound to
// Different mouse inputs
toolGroup.setToolActive(WindowLevelTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary, // Left Click
},
],
});
toolGroup.setToolActive(PanTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Auxiliary, // Middle Click
},
],
});
toolGroup.setToolActive(ZoomTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Secondary, // Right Click
},
],
});
// As the Stack Scroll mouse wheel is a tool using the `mouseWheelCallback`
// hook instead of mouse buttons, it does not need to assign any mouse button.
toolGroup.setToolActive(StackScrollTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Wheel }],
});
// Get Cornerstone imageIds and fetch metadata into RAM
// Instantiate a rendering engine
const renderingEngineId = "myRenderingEngine";
const renderingEngine = new RenderingEngine(renderingEngineId);
const viewportInputArray = [
{
viewportId: viewportIds[0],
type: ViewportType.ORTHOGRAPHIC,
element: element1,
defaultOptions: {
orientation: Enums.OrientationAxis.AXIAL,
background: <Types.Point3>[0.2, 0, 0.2]
}
},
{
viewportId: viewportIds[1],
type: ViewportType.ORTHOGRAPHIC,
element: element2,
defaultOptions: {
orientation: Enums.OrientationAxis.SAGITTAL,
background: <Types.Point3>[0.2, 0, 0.2]
}
},
{
viewportId: viewportIds[2],
type: ViewportType.ORTHOGRAPHIC,
element: element3,
defaultOptions: {
orientation: Enums.OrientationAxis.CORONAL,
background: <Types.Point3>[0.2, 0, 0.2]
}
}
];
renderingEngine.setViewports(viewportInputArray);
viewportInputArray.forEach(({ viewportId }) => {
toolGroup.addViewport(viewportId, renderingEngineId);
});
return async (imageIds: string[]) => {
// Define a volume in memory
const volume = await volumeLoader.createAndCacheVolume(volumeId, {
imageIds
});
// Set the volume to load
(volume as unknown as any).load()
// Set volumes on the viewports
return setVolumesForViewports(
renderingEngine,
[{ volumeId }],
viewportIds
).then(() => {
renderingEngine.renderViewports(viewportIds);
});
};
}
import { init as csRenderInit } from "@cornerstonejs/core";
import * as cornerstoneTools from "@cornerstonejs/tools";
import * as cornerstone from "@cornerstonejs/core";
import { init as csToolsInit } from "@cornerstonejs/tools";
import cornerstoneDICOMImageLoader from "@cornerstonejs/dicom-image-loader";
import { initProviders } from "./helpers/initProviders";
export function initVolumeLoader() {
cornerstone.volumeLoader.registerUnknownVolumeLoader(cornerstone.cornerstoneStreamingImageVolumeLoader);
cornerstone.volumeLoader.registerVolumeLoader(
"cornerstoneStreamingImageVolume",
cornerstone.cornerstoneStreamingImageVolumeLoader
);
cornerstone.volumeLoader.registerVolumeLoader(
"cornerstoneStreamingDynamicImageVolume",
cornerstone.cornerstoneStreamingDynamicImageVolumeLoader
);
}
export default async function initDemo(config?: any) {
(window as any).cornerstone = cornerstone;
(window as any).cornerstoneTools = cornerstoneTools;
initProviders();
cornerstoneDICOMImageLoader.init({
maxWebWorkers: 1,
});
initVolumeLoader();
await csRenderInit({
peerImport,
...(config?.core ? config.core : {}),
});
await csToolsInit();
}
/**
* This is one example of how to import peer modules that works with webpack
* It in fact just uses the default import from the browser, so it should work
* on any standards compliant ecmascript environment.
*/
export async function peerImport(moduleId: string) {
if (moduleId === "dicom-microscopy-viewer") {
return importGlobal("/dicom-microscopy-viewer/dicomMicroscopyViewer.min.js", "dicomMicroscopyViewer");
}
if (moduleId === "@icr/polyseg-wasm") {
return import("@icr/polyseg-wasm");
}
}
async function importGlobal(path: string, globalName: string) {
await import(/* webpackIgnore: true */ path);
return (window as unknown as any)[globalName];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment