|
@@ -9,6 +9,8 @@ import { SystemMode } from '@/states/systemModeSlice';
|
|
|
import store from '@/states/store';
|
|
|
import { clearAction } from '@/states/view/functionAreaSlice';
|
|
|
import { useDispatch } from 'react-redux';
|
|
|
+import { SplineROITool } from '@cornerstonejs/tools';
|
|
|
+import { eventTarget } from '@cornerstonejs/core';
|
|
|
|
|
|
const {
|
|
|
MagnifyTool,
|
|
@@ -25,6 +27,82 @@ const { MouseBindings } = csToolsEnums;
|
|
|
let toolGroup: cornerstoneTools.Types.IToolGroup;
|
|
|
let currentViewportId: string;
|
|
|
|
|
|
+function overlayRedRectangle() {
|
|
|
+ const viewport = cornerstone.getEnabledElementByViewportId(currentViewportId)
|
|
|
+ .viewport as cornerstone.StackViewport;
|
|
|
+ const viewportElement = viewport.element;
|
|
|
+ const annotations = cornerstoneTools.annotation.state.getAnnotations(
|
|
|
+ 'LinearSplineROI',
|
|
|
+ viewportElement
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!annotations || annotations.length === 0) {
|
|
|
+ console.log('No ROI annotations found');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const annotation = annotations[annotations.length - 1];
|
|
|
+ const points = annotation?.data?.handles?.points;
|
|
|
+
|
|
|
+ // 创建一个覆盖 Canvas
|
|
|
+ const canvas = document.createElement('canvas');
|
|
|
+ canvas.style.position = 'absolute';
|
|
|
+ canvas.width = viewportElement.clientWidth;
|
|
|
+ canvas.height = viewportElement.clientHeight;
|
|
|
+ viewportElement.firstChild?.appendChild(canvas);
|
|
|
+
|
|
|
+ const ctx = canvas.getContext('2d');
|
|
|
+ if (!ctx) {
|
|
|
+ throw new Error('Failed to get 2D context from canvas');
|
|
|
+ }
|
|
|
+ ctx.fillStyle = 'rgba(0, 0, 0, 1)';
|
|
|
+
|
|
|
+ // 将 ROI 坐标转换为 Canvas 坐标
|
|
|
+ if (!points) {
|
|
|
+ console.log('No points found in handles');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Convert all points to canvas coordinates
|
|
|
+ const z = viewport.getCurrentImageIdIndex() || 0;
|
|
|
+ const canvasPoints = points.map((point: Types.Point2 | Types.Point3) => {
|
|
|
+ const point3D: Types.Point3 =
|
|
|
+ point.length === 2 ? [point[0], point[1], z] : point;
|
|
|
+ return viewport.worldToCanvas(point3D);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Log for debugging
|
|
|
+ console.log('Canvas Points:', canvasPoints);
|
|
|
+
|
|
|
+ // Draw the polygon
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.rect(0, 0, canvas.width, canvas.height); // Full canvas for evenodd rule
|
|
|
+ ctx.moveTo(canvasPoints[0][0], canvasPoints[0][1]); // Start at the first point
|
|
|
+ for (let i = 1; i < canvasPoints.length; i++) {
|
|
|
+ ctx.lineTo(canvasPoints[i][0], canvasPoints[i][1]); // Connect to subsequent points
|
|
|
+ }
|
|
|
+ ctx.closePath(); // Close the polygon
|
|
|
+ ctx.fill('evenodd'); // Fill with red
|
|
|
+}
|
|
|
+
|
|
|
+eventTarget.addEventListener(
|
|
|
+ cornerstoneTools.Enums.Events.ANNOTATION_COMPLETED,
|
|
|
+ (evt) => {
|
|
|
+ const { annotation } = evt.detail;
|
|
|
+ console.log('Annotation completed event:', annotation);
|
|
|
+ if (annotation.metadata.toolName === 'LinearSplineROI') {
|
|
|
+ console.log('SplineROITool annotation completed:', annotation);
|
|
|
+ overlayRedRectangle();
|
|
|
+ //取消工具激活状态
|
|
|
+ const toolGroup = ToolGroupManager.getToolGroup('STACK_TOOL_GROUP_ID');
|
|
|
+ if (!toolGroup) {
|
|
|
+ console.log('toolGroup not found');
|
|
|
+ }
|
|
|
+ toolGroup?.setToolPassive('LinearSplineROI', { removeAllBindings: true });
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
function registerTools(viewportId, renderingEngineId) {
|
|
|
// Add tools to Cornerstone3D
|
|
|
cornerstoneTools.addTool(MagnifyTool);
|
|
@@ -162,6 +240,22 @@ function deleteSelectedMark(): void {
|
|
|
}
|
|
|
viewport.render();
|
|
|
}
|
|
|
+
|
|
|
+function addMask(): void {
|
|
|
+ // Implement the logic to add a mask
|
|
|
+ console.log('Adding Mask');
|
|
|
+ // Add the specific logic to add a mask here
|
|
|
+ cornerstoneTools.addTool(SplineROITool);
|
|
|
+ toolGroup.addTool(SplineROITool.toolName);
|
|
|
+ toolGroup.addToolInstance('LinearSplineROI', SplineROITool.toolName, {
|
|
|
+ spline: {
|
|
|
+ type: SplineROITool.SplineTypes.Linear,
|
|
|
+ },
|
|
|
+ });
|
|
|
+ toolGroup.setToolActive('LinearSplineROI', {
|
|
|
+ bindings: [{ mouseButton: MouseBindings.Primary }],
|
|
|
+ });
|
|
|
+}
|
|
|
function HorizontalFlip(): void {
|
|
|
const viewport = cornerstone.getEnabledElementByViewportId(currentViewportId)
|
|
|
.viewport as cornerstone.StackViewport;
|
|
@@ -509,8 +603,7 @@ const StackViewer = ({
|
|
|
}
|
|
|
break;
|
|
|
case 'Crop Image':
|
|
|
- // Implement the logic to crop the image
|
|
|
- console.log('Cropping Image');
|
|
|
+ addMask();
|
|
|
break;
|
|
|
case 'Delete Digital Mask':
|
|
|
// Implement the logic to delete the digital mask
|