|
@@ -9,9 +9,17 @@ import { SystemMode } from '@/states/systemModeSlice';
|
|
import store from '@/states/store';
|
|
import store from '@/states/store';
|
|
import { clearAction } from '@/states/view/functionAreaSlice';
|
|
import { clearAction } from '@/states/view/functionAreaSlice';
|
|
import { useDispatch } from 'react-redux';
|
|
import { useDispatch } from 'react-redux';
|
|
-import { IP_PORT } from '@/API/config';
|
|
|
|
|
|
|
|
-const { PanTool, WindowLevelTool, StackScrollTool, ZoomTool, LabelTool, ToolGroupManager, Enums: csToolsEnums, PlanarRotateTool } = cornerstoneTools;
|
|
|
|
|
|
+const {
|
|
|
|
+ PanTool,
|
|
|
|
+ WindowLevelTool,
|
|
|
|
+ StackScrollTool,
|
|
|
|
+ ZoomTool,
|
|
|
|
+ LabelTool,
|
|
|
|
+ ToolGroupManager,
|
|
|
|
+ Enums: csToolsEnums,
|
|
|
|
+ PlanarRotateTool,
|
|
|
|
+} = cornerstoneTools;
|
|
const { MouseBindings } = csToolsEnums;
|
|
const { MouseBindings } = csToolsEnums;
|
|
let toolGroup: cornerstoneTools.Types.IToolGroup;
|
|
let toolGroup: cornerstoneTools.Types.IToolGroup;
|
|
let currentViewportId: string;
|
|
let currentViewportId: string;
|
|
@@ -80,8 +88,6 @@ function registerTools(viewportId, renderingEngineId) {
|
|
],
|
|
],
|
|
});
|
|
});
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
toolGroup.addViewport(viewportId, renderingEngineId);
|
|
toolGroup.addViewport(viewportId, renderingEngineId);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -97,7 +103,27 @@ function addRLabel(viewportId) {
|
|
toolGroup.setToolPassive(LabelTool.toolName, { removeAllBindings: true });
|
|
toolGroup.setToolPassive(LabelTool.toolName, { removeAllBindings: true });
|
|
}
|
|
}
|
|
|
|
|
|
-const StackViewer = ({ imageIndex }) => {
|
|
|
|
|
|
+function deleteSelectedMark(): void {
|
|
|
|
+ const viewport =
|
|
|
|
+ cornerstone.getEnabledElementByViewportId(currentViewportId).viewport;
|
|
|
|
+ const allAnnotations = cornerstoneTools.annotation.state.getAllAnnotations();
|
|
|
|
+ for (const annotation of allAnnotations) {
|
|
|
|
+ if (annotation.data.text === 'L' || annotation.data.text === 'R') {
|
|
|
|
+ cornerstoneTools.annotation.state.removeAnnotation(
|
|
|
|
+ annotation.annotationUID!
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ viewport.render();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const StackViewer = ({
|
|
|
|
+ imageIndex = 0,
|
|
|
|
+ imageUrls = [],
|
|
|
|
+}: {
|
|
|
|
+ imageIndex?: number;
|
|
|
|
+ imageUrls?: string[];
|
|
|
|
+}) => {
|
|
const elementRef = useRef<HTMLDivElement>(null);
|
|
const elementRef = useRef<HTMLDivElement>(null);
|
|
const action = useSelector((state: RootState) => state.functionArea.action);
|
|
const action = useSelector((state: RootState) => state.functionArea.action);
|
|
const dispatch = useDispatch();
|
|
const dispatch = useDispatch();
|
|
@@ -137,7 +163,9 @@ const StackViewer = ({ imageIndex }) => {
|
|
|
|
|
|
// Instantiate a rendering engine
|
|
// Instantiate a rendering engine
|
|
const renderingEngineId = 'myRenderingEngine';
|
|
const renderingEngineId = 'myRenderingEngine';
|
|
- const renderingEngine = new cornerstone.RenderingEngine(renderingEngineId);
|
|
|
|
|
|
+ const renderingEngine = new cornerstone.RenderingEngine(
|
|
|
|
+ renderingEngineId
|
|
|
|
+ );
|
|
|
|
|
|
const viewportId = 'CT_AXIAL_STACK';
|
|
const viewportId = 'CT_AXIAL_STACK';
|
|
currentViewportId = viewportId;
|
|
currentViewportId = viewportId;
|
|
@@ -151,18 +179,12 @@ const StackViewer = ({ imageIndex }) => {
|
|
registerTools(viewportId, renderingEngineId);
|
|
registerTools(viewportId, renderingEngineId);
|
|
|
|
|
|
// Get the stack viewport that was created
|
|
// Get the stack viewport that was created
|
|
- const viewport = renderingEngine.getViewport(viewportId) as cornerstone.Types.IStackViewport;
|
|
|
|
|
|
+ const viewport = renderingEngine.getViewport(
|
|
|
|
+ viewportId
|
|
|
|
+ ) as cornerstone.Types.IStackViewport;
|
|
|
|
|
|
// 给定一个dcm文件路径,加载并显示出来
|
|
// 给定一个dcm文件路径,加载并显示出来
|
|
- const imageId1 = 'dicomweb:https://ohif-assets-new.s3.us-east-1.amazonaws.com/ACRIN-Regular/CT+CT+IMAGES/CT000000.dcm';
|
|
|
|
- const imageId2 = 'dicomweb:https://ohif-assets-new.s3.us-east-1.amazonaws.com/ACRIN-Regular/CT+CT+IMAGES/CT000005.dcm';
|
|
|
|
- const imageId3 = 'dicomweb:https://ohif-dicom-json-example.s3.amazonaws.com/LIDC-IDRI-0001/01-01-2000-30178/3000566.000000-03192/1-001.dcm';
|
|
|
|
- const imageId4 = `dicomweb:${IP_PORT}/dr/api/v1/auth/image/dcm/CTImage.dcm`;
|
|
|
|
- const imageId5 = `dicomweb:${IP_PORT}/dr/api/v1/pub/dcm/CTImage.dcm`;
|
|
|
|
- const imageId6 = `dicomweb:${IP_PORT}/dr/api/v1/auth/image/dcm/CTImage.dcm`;
|
|
|
|
- const imageId7 = `dicomweb:${IP_PORT}/dr/api/v1/pub/dcm/CTImage.dcm`;
|
|
|
|
- imageIndex = 6;
|
|
|
|
- await viewport.setStack([imageId1, imageId2, imageId3, imageId4, imageId5, imageId6, imageId7], imageIndex);
|
|
|
|
|
|
+ await viewport.setStack(imageUrls, imageIndex);
|
|
viewport.render();
|
|
viewport.render();
|
|
};
|
|
};
|
|
|
|
|
|
@@ -186,7 +208,9 @@ const StackViewer = ({ imageIndex }) => {
|
|
const position: Types.Point3 = [100, 100, 0]; // Example position
|
|
const position: Types.Point3 = [100, 100, 0]; // Example position
|
|
const text = 'L'; // Predefined text
|
|
const text = 'L'; // Predefined text
|
|
LabelTool.hydrate(currentViewportId, position, text);
|
|
LabelTool.hydrate(currentViewportId, position, text);
|
|
- toolGroup.setToolPassive(LabelTool.toolName, { removeAllBindings: true });
|
|
|
|
|
|
+ toolGroup.setToolPassive(LabelTool.toolName, {
|
|
|
|
+ removeAllBindings: true,
|
|
|
|
+ });
|
|
// const enabledElement = cornerstone.getEnabledElementByViewportId(currentViewportId);
|
|
// const enabledElement = cornerstone.getEnabledElementByViewportId(currentViewportId);
|
|
// cursors.elementCursor.resetElementCursor(elementRef.current as HTMLDivElement);
|
|
// cursors.elementCursor.resetElementCursor(elementRef.current as HTMLDivElement);
|
|
break;
|
|
break;
|
|
@@ -195,36 +219,20 @@ const StackViewer = ({ imageIndex }) => {
|
|
addRLabel(currentViewportId);
|
|
addRLabel(currentViewportId);
|
|
console.log('Adding R Mark');
|
|
console.log('Adding R Mark');
|
|
break;
|
|
break;
|
|
- case 'Delete Selected Mark':
|
|
|
|
- // Implement the logic to delete the selected mark
|
|
|
|
- const viewport = cornerstone.getEnabledElementByViewportId(currentViewportId).viewport;
|
|
|
|
- const allAnnotations = cornerstoneTools.annotation.state.getAllAnnotations();
|
|
|
|
- // const allAnnotations = cornerstoneTools.annotation.state.getAnnotations(LabelTool.toolName, element.element);
|
|
|
|
- console.log(`allAnnotations 数量:${allAnnotations.length}`);
|
|
|
|
- for (const annotation of allAnnotations) {
|
|
|
|
- if (annotation.data.text === 'L' || annotation.data.text === 'R') {
|
|
|
|
- console.log(`Deleting annotation with UID: ${annotation.annotationUID}`);
|
|
|
|
- cornerstoneTools.annotation.state.removeAnnotation(annotation.annotationUID!);
|
|
|
|
- }
|
|
|
|
- // cornerstoneTools.annotation.state.removeAnnotation(annotation.annotationUID!);
|
|
|
|
- }
|
|
|
|
- // 触发视口重新渲染
|
|
|
|
- viewport.render();
|
|
|
|
- console.log('Deleting Selected Mark');
|
|
|
|
|
|
+ case 'Delete Selected Mark': {
|
|
|
|
+ deleteSelectedMark();
|
|
break;
|
|
break;
|
|
- case 'Horizontal Flip':
|
|
|
|
|
|
+ }
|
|
|
|
+ case 'Horizontal Flip': {
|
|
// Implement the logic to flip the image horizontally
|
|
// Implement the logic to flip the image horizontally
|
|
console.log('Flipping Image Horizontally');
|
|
console.log('Flipping Image Horizontally');
|
|
break;
|
|
break;
|
|
- // case 'Vertical Flip':
|
|
|
|
- // { // Implement the logic to flip the image vertically
|
|
|
|
- // console.log('Flipping Image Vertically');
|
|
|
|
- // }
|
|
|
|
- // break;
|
|
|
|
- case 'Rotate Counterclockwise 90':
|
|
|
|
|
|
+ }
|
|
|
|
+ case 'Rotate Counterclockwise 90': {
|
|
// Implement the logic to rotate the image counterclockwise
|
|
// Implement the logic to rotate the image counterclockwise
|
|
console.log('Rotating Image Counterclockwise 90°');
|
|
console.log('Rotating Image Counterclockwise 90°');
|
|
break;
|
|
break;
|
|
|
|
+ }
|
|
case 'Rotate Clockwise 90':
|
|
case 'Rotate Clockwise 90':
|
|
// Implement the logic to rotate the image clockwise
|
|
// Implement the logic to rotate the image clockwise
|
|
console.log('Rotating Image Clockwise 90°');
|
|
console.log('Rotating Image Clockwise 90°');
|
|
@@ -234,9 +242,13 @@ const StackViewer = ({ imageIndex }) => {
|
|
{
|
|
{
|
|
const planar = toolGroup.getToolInstance(PlanarRotateTool.toolName); // Reset rotation angle
|
|
const planar = toolGroup.getToolInstance(PlanarRotateTool.toolName); // Reset rotation angle
|
|
const isActive = planar.mode === csToolsEnums.ToolModes.Active;
|
|
const isActive = planar.mode === csToolsEnums.ToolModes.Active;
|
|
- console.log(`PlanarRotateTool is currently ${isActive ? 'active' : 'inactive'}`);
|
|
|
|
|
|
+ console.log(
|
|
|
|
+ `PlanarRotateTool is currently ${isActive ? 'active' : 'inactive'}`
|
|
|
|
+ );
|
|
if (isActive) {
|
|
if (isActive) {
|
|
- toolGroup.setToolPassive(PlanarRotateTool.toolName, { removeAllBindings: true });
|
|
|
|
|
|
+ toolGroup.setToolPassive(PlanarRotateTool.toolName, {
|
|
|
|
+ removeAllBindings: true,
|
|
|
|
+ });
|
|
} else {
|
|
} else {
|
|
toolGroup.setToolActive(PlanarRotateTool.toolName, {
|
|
toolGroup.setToolActive(PlanarRotateTool.toolName, {
|
|
bindings: [
|
|
bindings: [
|
|
@@ -276,7 +288,10 @@ const StackViewer = ({ imageIndex }) => {
|
|
case 'Invert Contrast':
|
|
case 'Invert Contrast':
|
|
// Implement the logic to invert the contrast
|
|
// Implement the logic to invert the contrast
|
|
{
|
|
{
|
|
- const viewport = cornerstone.getEnabledElementByViewportId(currentViewportId).viewport;
|
|
|
|
|
|
+ const viewport =
|
|
|
|
+ cornerstone.getEnabledElementByViewportId(
|
|
|
|
+ currentViewportId
|
|
|
|
+ ).viewport;
|
|
const targetBool = !viewport.getProperties().invert;
|
|
const targetBool = !viewport.getProperties().invert;
|
|
viewport.setProperties({
|
|
viewport.setProperties({
|
|
invert: targetBool,
|
|
invert: targetBool,
|
|
@@ -356,7 +371,7 @@ const StackViewer = ({ imageIndex }) => {
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- dispatch(clearAction());//清理后可连续同一个action触发响应
|
|
|
|
|
|
+ dispatch(clearAction()); //清理后可连续同一个action触发响应
|
|
}
|
|
}
|
|
}, [action]);
|
|
}, [action]);
|
|
|
|
|