瀏覽代碼

fit standard line info

melon.yin 2 年之前
父節點
當前提交
36bc7ba7e6

+ 3 - 1
lib/measure_page_test.dart

@@ -46,7 +46,9 @@ class _MeasureTestPageState extends State<MeasureTestPage> {
       // "http://cdn-bj.fis.plus/0B344F48BA574ECD82B7FEDB8848421A.vid";//单幅TM
       // "http://cdn-bj.fis.plus/6B6E069659D14E7299EB9F6EFCDE9C8C.vid"; //双幅单TissueConvex
       // "http://cdn-bj.fis.plus/062643B82365437DB95F3811580AF3ED.vid"; //四幅单模式
-      "http://cdn-bj.fis.plus/EA90D146049D416E8E466B7446E00001.vid"; //四幅Doppler
+      // "http://cdn-bj.fis.plus/EA90D146049D416E8E466B7446E00001.vid"; //四幅Doppler
+      "http://cdn-bj.fis.plus/3rd_linearTvTissue2.vid"; //魔盒
+  // "http://cdn-bj.fis.plus/81FFF8E5E078473FA687FBE81C4869B1.vid"; // 魔盒TV
   static const C_CONVEX_TISSUE =
       "http://cdn-bj.fis.plus/FEB1AAE5D9C24839BEE31B16E8CB450A.vid";
 

+ 6 - 3
lib/process/workspace/application.dart

@@ -29,7 +29,9 @@ import '../visual/visual.dart';
 import 'visual_loader.dart';
 
 class Application implements IApplication {
+  // ignore: constant_identifier_names
   static const C_VID_THIRDPART_NAME = "ThirdPart";
+
   late VidUsProbe _probe;
   VidUsImage? _frame;
   List<IVisual>? _visuals;
@@ -209,7 +211,7 @@ class Application implements IApplication {
     bool frameLoaded = _frame != null;
     _frame = frame;
     if (!frameLoaded && canMeasure) {
-      _loadVisuals();
+      loadVisuals();
     }
   }
 
@@ -376,7 +378,7 @@ class Application implements IApplication {
     _clear();
     if (canMeasure) {
       if (frameData != null) {
-        _loadVisuals();
+        loadVisuals();
       }
     }
   }
@@ -395,7 +397,8 @@ class Application implements IApplication {
     _updateRender();
   }
 
-  void _loadVisuals() {
+  @protected
+  void loadVisuals() {
     _clearVisuals();
     _visuals = convertVisuals();
     // 默认第一个区域为活动域

+ 18 - 2
lib/process/workspace/measure_controller.dart

@@ -1,6 +1,7 @@
 import 'package:fis_measure/interfaces/process/workspace/exam_info.dart';
 import 'package:fis_measure/interfaces/process/workspace/measure_controller.dart';
 import 'package:fis_measure/process/workspace/application.dart';
+import 'package:fis_measure/process/workspace/third_part/application.dart';
 import 'package:fis_measure/view/player/controller.dart';
 import 'package:fis_measure/view/player/enums.dart';
 import 'package:fis_measure/view/player/events.dart';
@@ -86,18 +87,21 @@ class MeasureController implements IMeasureController {
         Get.put<IPlayerController>(VidPlayerController(dataHost: dataHost));
 
     dataHost.frameLoaded.addListener(_onFrameLoaded);
-    playerController.load().then((_) {
+    playerController.load().then((_) async {
       if (playerController.status != VidPlayStatus.ready) {
         throw FlutterError("Vid file load fail.");
       }
-      _application = Get.put<IApplication>(Application(_vidDataHost!.probe));
       playerController.eventHandler.addListener(_onPlayerEnvent);
 
+      // 构建应用
+      await _buildApplication();
+
       // 立即播放
       Future.delayed(const Duration(milliseconds: 100), () {
         playerController.play();
       });
 
+      // 通知图像加载完成
       imageLoaded.emit(sender, examInfo.selectedImage);
     });
   }
@@ -111,4 +115,16 @@ class MeasureController implements IMeasureController {
       workingApplication.canOperate = e.status == VidPlayStatus.pause;
     }
   }
+
+  Future<void> _buildApplication() async {
+    final is3rd = dataHost.probe.name == Application.C_VID_THIRDPART_NAME;
+    IApplication app;
+    if (is3rd) {
+      final vidData = await dataHost.getData();
+      app = ThirdPartApplication(dataHost.probe, vidData!.extendedData);
+    } else {
+      app = Application(dataHost.probe);
+    }
+    _application = Get.put<IApplication>(app);
+  }
 }

+ 25 - 2
lib/process/workspace/third_part/application.dart

@@ -1,18 +1,41 @@
+import 'dart:typed_data';
+
 import 'package:fis_measure/interfaces/date_types/rect_region.dart';
 import 'package:fis_measure/interfaces/date_types/size.dart';
 import 'package:fis_measure/interfaces/process/visuals/visual.dart';
+import 'package:vid/us/vid_us_image.dart';
 import 'package:vid/us/vid_us_probe.dart';
 
 import '../application.dart';
+import 'pixel_space.dart';
+import 'standard_line.dart';
 import 'visual.dart';
 
 class ThirdPartApplication extends Application {
-  ThirdPartApplication(VidUsProbe probe) : super(probe);
+  ThirdPartApplication(
+    VidUsProbe probe,
+    Uint8List extendedData,
+  ) : super(probe) {
+    standardLine.loadFromVidExtData(extendedData);
+    standardLine.pixelSpacingChanged.addListener(_onPixelSpacingChanged);
+  }
+
+  final StandardLine standardLine = StandardLine();
 
   @override
   List<IVisual> convertVisuals() {
     final visualData = frameData!.visuals.first;
     final region = RectRegion.size(DSize(1, 1));
-    return [ThirdPartVisual(visualData, region)];
+    return [ThirdPartVisual(this, visualData, region)];
+  }
+
+  // @override
+  // void loadFrame(VidUsImage frame) {
+
+  //   super.loadFrame(frame);
+  // }
+
+  void _onPixelSpacingChanged(Object sender, PixelSpacing? pixelSpacing) {
+    loadVisuals();
   }
 }

+ 41 - 8
lib/process/workspace/third_part/standard_line.dart

@@ -2,15 +2,17 @@
 
 import 'dart:typed_data';
 
+import 'package:fis_common/event/event_type.dart';
 import 'package:fis_vid_ext/vid_extended_data.dart';
 import 'package:fis_vid_ext/vid_tag.dart';
 import 'package:fis_vid_ext/vid_value.dart';
 
 import 'pixel_space.dart';
 
+/// 参考线
 class StandardLine {
-  /// Default Standard Line Physical Length (unit mm)
-  static const double DefaultPhysicsLength = 40;
+  /// Default Standard Line Physical Length (unit cm)
+  static const double DefaultPhysicsLength = 4.0;
 
   /// 0028,0030   PixelSpacing from dicom
   static final VidTag DicomTagPixelSpacing = VidTag("0028", "0030");
@@ -27,27 +29,43 @@ class StandardLine {
   /// 0018, 6026 Physical Units Y
   static final VidTag DicomTagPhysicalUnitsY = VidTag("0018", "6026");
 
-  PixelSpacing? _currentPixelSpacing;
+  PixelSpacing _currentPixelSpacing = PixelSpacing();
   double _physicsLength = DefaultPhysicsLength;
+  double _pixelLength = 0.0;
+  double _perPixelPhysicalLength = 0.0;
 
+  /// 参考线物理长度(cm)
   double get physicsLength => _physicsLength;
   set physicsLength(double val) {
     if (val != _physicsLength) {
       _physicsLength = val;
+      _onLineLengthChanged();
     }
   }
 
+  /// 参考线像素长度
+  double get pixelLength => _pixelLength;
+  set pixelLength(double val) {
+    if (val != _pixelLength) {
+      _pixelLength = val;
+      _onLineLengthChanged();
+    }
+  }
+
+  /// 单位像素物理长度(cm)
+  double get perPixelPhysicalLength => _perPixelPhysicalLength;
+
   /// 当前像素距离尺
-  PixelSpacing? get currentPixelSpacing => _currentPixelSpacing;
-  set currentPixelSpacing(PixelSpacing? val) {
+  PixelSpacing get currentPixelSpacing => _currentPixelSpacing;
+  set currentPixelSpacing(PixelSpacing val) {
     if (val != _currentPixelSpacing) {
       _currentPixelSpacing = val;
       _onPixelSpacingChanged();
     }
   }
 
-  /// 是否需要设置像素距离尺
-  bool get needSetPixelSpacing => currentPixelSpacing == null;
+  /// 像素距离尺变化事件
+  final pixelSpacingChanged = FEventHandler<PixelSpacing?>();
 
   /// 通过vid扩展信息加载像素距离信息
   void loadFromVidExtData(Uint8List bytes) {
@@ -86,8 +104,23 @@ class StandardLine {
     }
   }
 
+  void _onLineLengthChanged() {
+    final physicalDeltaX = physicsLength * 10 / pixelLength;
+    final physicalDeltaY = physicalDeltaX;
+    currentPixelSpacing = PixelSpacing.fill(physicalDeltaX, physicalDeltaY);
+  }
+
   void _onPixelSpacingChanged() {
-// _physicsLength
+    _perPixelPhysicalLength =
+        _getPixelLengthWithUnit(currentPixelSpacing.physicalDeltaX);
+  }
+
+  double _getPixelLengthWithUnit(double length) {
+    // if (_mearsureUnit == MearsureUnit.cm)
+    // {
+    length = length / 10;
+    // }
+    return length;
   }
 
   IVidValue? _getVidValueByTag(VidTag vidTag, VidExtendedData extendedData) {

+ 8 - 2
lib/process/workspace/third_part/visual.dart

@@ -3,11 +3,17 @@ import 'package:fis_measure/interfaces/process/visuals/visual_area.dart';
 import 'package:fis_measure/process/visual/visual.dart';
 import 'package:vid/us/vid_us_visual.dart';
 
+import 'application.dart';
 import 'visual_area.dart';
 
 class ThirdPartVisual extends VisualBase {
-  ThirdPartVisual(VidUsVisual visualData, RectRegion region)
-      : super(visualData, region);
+  ThirdPartVisual(
+    this.application,
+    VidUsVisual visualData,
+    RectRegion region,
+  ) : super(visualData, region);
+
+  final ThirdPartApplication application;
 
   @override
   List<IVisualArea> loadAreas() {

+ 8 - 3
lib/process/workspace/third_part/visual_area.dart

@@ -1,9 +1,8 @@
 import 'package:fis_measure/interfaces/date_types/rect_region.dart';
-import 'package:fis_measure/interfaces/process/visuals/tissue_area.dart';
 import 'package:fis_measure/interfaces/process/visuals/visual.dart';
 import 'package:fis_measure/process/physical_coordinates/empty_tissue.dart';
 import 'package:fis_measure/process/visual/tissue_area.dart';
-import 'package:fis_measure/process/visual/visual_area.dart';
+import 'package:fis_measure/process/workspace/third_part/visual.dart';
 import 'package:vid/us/vid_us_unit.dart';
 import 'package:vid/us/vid_us_visual_area_type.dart';
 import 'package:vid/us/vid_us_mode.dart';
@@ -21,7 +20,13 @@ class ThirdPartVisualArea extends TissueArea {
   @override
   void loadData() {
     layoutRegion = RectRegion.fill(0, 0, 1, 1);
-    RectRegion region = RectRegion.fill(0, 0, 1, 1);
+    final application = (visual as ThirdPartVisual).application;
+    final frame = application.frameData!;
+    final pixelLength = application.standardLine.perPixelPhysicalLength;
+
+    final width = frame.width * pixelLength;
+    final height = frame.height * pixelLength;
+    RectRegion region = RectRegion.fill(0, 0, width, height);
     viewport = ThirdPartViewPort(
       this,
       EmptyTissuePhysicalCoordinate(),