import 'dart:convert'; import 'dart:ui'; import 'package:fis_measure/interfaces/date_types/point.dart'; import 'package:fis_measure/process/primitives/carotid_imt.dart'; import 'package:fis_measure/utils/js_utils.dart' if (dart.library.io) 'package:fis_measure/utils/js_utils4native.dart' if (dart.library.html) 'package:fis_measure/utils/js_utils.dart'; import 'package:vid/us/vid_us_unit.dart'; import 'calculator.dart'; class CarotidCal extends Calculator { CarotidCal(CarotidIMT ref, this.type) : super(ref); String type = ''; @override void calculate() { if (ref.feature == null) return; final p1 = ref.feature!.startPoint; final p2 = ref.feature!.endPoint; //左上顶点 final leftTopPoint = DPoint(p1.x < p2.x ? p1.x : p2.x, p1.y < p2.y ? p1.y : p2.y); //右下顶点 final rightBottomPoint = DPoint(p1.x > p2.x ? p1.x : p2.x, p1.y > p2.y ? p1.y : p2.y); //图片尺寸 final imageSize = ref.application.carotid2DSize; //画布尺寸 final canavsSize = ref.application.displaySize; //图像缩放比 final imageScale = ref.application.displayScaleRatio; //标准画布尺寸 final stdCanavsSize = Size(canavsSize.width / imageScale, canavsSize.height / imageScale); //Vid图像左上顶点的像素坐标 final imageLeftTopPoint = DPoint( (stdCanavsSize.width - imageSize.width) / 2, (stdCanavsSize.height - imageSize.height) / 2); //Vid图像右下顶点的像素坐标 final imageRightBottomPoint = DPoint(imageLeftTopPoint.x + imageSize.width, imageLeftTopPoint.y + imageSize.height); //选区左上顶点的像素坐标 final rectLeftTopPoint = DPoint(stdCanavsSize.width * leftTopPoint.x, stdCanavsSize.height * leftTopPoint.y); //选区右下顶点的像素坐标 final rectRightBottomPoint = DPoint( stdCanavsSize.width * rightBottomPoint.x, stdCanavsSize.height * rightBottomPoint.y); /// 在图像外的点改到图像边缘上 if (rectLeftTopPoint.x < imageLeftTopPoint.x) { rectLeftTopPoint.x = imageLeftTopPoint.x; } if (rectLeftTopPoint.x > imageRightBottomPoint.x) { rectLeftTopPoint.x = imageRightBottomPoint.x; } if (rectLeftTopPoint.y < imageLeftTopPoint.y) { rectLeftTopPoint.y = imageLeftTopPoint.y; } if (rectLeftTopPoint.y > imageRightBottomPoint.y) { rectLeftTopPoint.y = imageRightBottomPoint.y; } if (rectRightBottomPoint.x > imageRightBottomPoint.x) { rectRightBottomPoint.x = imageRightBottomPoint.x; } if (rectRightBottomPoint.x < imageLeftTopPoint.x) { rectRightBottomPoint.x = imageLeftTopPoint.x; } if (rectRightBottomPoint.y > imageRightBottomPoint.y) { rectRightBottomPoint.y = imageRightBottomPoint.y; } if (rectRightBottomPoint.y < imageLeftTopPoint.y) { rectRightBottomPoint.y = imageLeftTopPoint.y; } final rectLeft = (rectLeftTopPoint.x - imageLeftTopPoint.x).round(); final rectTop = (rectLeftTopPoint.y - imageLeftTopPoint.y).round(); final rectWidth = (rectRightBottomPoint.x - rectLeftTopPoint.x).round(); final rectHeight = (rectRightBottomPoint.y - rectLeftTopPoint.y).round(); String measureItemType = 'AntMeasureItem'; if (type == 'Ant.CCA IMT') { measureItemType = 'AntMeasureItem'; } else if (type == 'Post.CCA IMT') { measureItemType = 'PostMeasureItem'; } else if (type == 'Both.CCA IMT') { measureItemType = 'AntAndPostMeasureItem'; } final params = "{'MeasureItemType':'$measureItemType','IntimaRect':{'Left':$rectLeft,'Top':$rectTop,'Width':$rectWidth,'Height':$rectHeight}}"; String description = "IMT\n Measuring"; updateStringValue(description); List getPointsFromStrList(List pointsStr) { final points = []; for (var point in pointsStr) { final xyStr = point.split(','); points.add(Offset((double.parse(xyStr[0]) + imageLeftTopPoint.x), (double.parse(xyStr[1]) + imageLeftTopPoint.y))); } return points; } /// [Carotid] ✅在此处通知 Shell 计算,获取 description,touch/mouse finished 时绘制结果 try { callShellMethod('getMeasureResult', [params]).callMethod( 'then', [ (result) { final feature = ref.feature!; // print("getMeasureResult: $result"); if (result == 'error') { description = "\n Measure failed"; updateStringValue(description); ref.application.updateRenderReady.emit(this, null); return; } final res = jsonDecode(result); if (res['ErrorCode'].toString() == "1000") { if (type != 'Both.CCA IMT') { description = "\n Max: ${res['MaxThickness'].toStringAsFixed(2)}mm\n Min: ${res['MinThickness'].toStringAsFixed(2)}mm\n Avg: ${res['AverageThickness'].toStringAsFixed(2)}mm\n SD: ${res['SdThickness'].toStringAsFixed(2)}mm"; } else { description = "\n Ant Max: ${res['LowerMeasureResult']['MaxThickness'].toStringAsFixed(2)}mm\n Ant.Min: ${res['LowerMeasureResult']['MinThickness'].toStringAsFixed(2)}mm\n Ant.Avg: ${res['LowerMeasureResult']['AverageThickness'].toStringAsFixed(2)}mm\n Ant.SD: ${res['LowerMeasureResult']['SdThickness'].toStringAsFixed(2)}mm\n Post.Max: ${res['UpperMeasureResult']['MaxThickness'].toStringAsFixed(2)}mm\n Post.Min: ${res['UpperMeasureResult']['MinThickness'].toStringAsFixed(2)}mm\n Post.Avg: ${res['UpperMeasureResult']['AverageThickness'].toStringAsFixed(2)}mm\n Post.SD: ${res['UpperMeasureResult']['SdThickness'].toStringAsFixed(2)}mm"; } if (type != 'Both.CCA IMT') { feature.offsetsList .add(getPointsFromStrList(res['PointLower'])); feature.offsetsList .add(getPointsFromStrList(res['PointUpper'])); } else { feature.offsetsList.add(getPointsFromStrList( res['LowerMeasureResult']['PointLower'])); feature.offsetsList.add(getPointsFromStrList( res['LowerMeasureResult']['PointUpper'])); feature.offsetsList.add(getPointsFromStrList( res['UpperMeasureResult']['PointLower'])); feature.offsetsList.add(getPointsFromStrList( res['UpperMeasureResult']['PointUpper'])); } } else { description = "\n Measure failed"; } updateStringValue(description); /// [Carotid] ✅在此处通知canvas 重绘结果 ref.application.updateRenderReady.emit(this, null); }, ], ); } catch (e) { updateStringValue("\n Measure failed"); // } } }