measure_3d_view_controller.dart 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:ui' as ui;
  4. import 'package:fis_common/event/event_type.dart';
  5. import 'package:fis_jsonrpc/services/index.dart';
  6. import 'package:fis_measure/interfaces/process/workspace/measure_3d_view_controller.dart';
  7. import 'package:fis_measure/utils/js_utils.dart'
  8. if (dart.library.io) 'package:fis_measure/utils/js_utils4native.dart'
  9. if (dart.library.html) 'package:fis_measure/utils/js_utils.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:vid/us/vid_us_image.dart';
  12. class Measure3DViewController implements IMeasure3DViewController {
  13. Measure3DViewController();
  14. /// [Carotid] ✅Measure3DView 控制器
  15. CarotidResultDTO _carotidResult = CarotidResultDTO();
  16. String _recordId = "";
  17. List<Ultra3DResourceInfo> _ultra3DResourceInfoList = [];
  18. bool _exist3DData = false;
  19. bool _enable2DMeasure = false;
  20. bool isShell = ifCurEnvIsShell;
  21. /// 模型切面标准宽度
  22. Size stdSize = const Size(599, 400);
  23. VidUsImage? _image4Measure;
  24. MeasureMode _curMeasureMode = MeasureMode.vidMode;
  25. ///3D模式下进入颈动脉2D模式
  26. void changeModeTo2DMeasure() {
  27. curMeasureMode = MeasureMode.carotid2DMode;
  28. initParams();
  29. updatePlayerMode.emit(this, MeasureMode.carotid2DMode);
  30. }
  31. ///vid 2D模式下进入3D测量模式
  32. void changeModeTo3DMode() {
  33. curMeasureMode = MeasureMode.carotid3DMode;
  34. initParams();
  35. updatePlayerMode.emit(this, MeasureMode.carotid3DMode);
  36. }
  37. /// 颈动脉2D、3D模式回到vid 2D测量模式
  38. void backToVidMode() {
  39. initParams();
  40. resetTone();
  41. curMeasureMode = MeasureMode.vidMode;
  42. updatePlayerMode.emit(this, MeasureMode.vidMode);
  43. }
  44. ///[Carotid] ✅通知 shell 下载全部模型文件,_ultra3DResourceInfoList 中的第一个元素为当前操作的元素
  45. void notifyShellLoadAllModel() {
  46. if (_ultra3DResourceInfoList.isNotEmpty) {
  47. final Ultr3DParameter ultra3DParameter =
  48. Ultr3DParameter(_recordId, _ultra3DResourceInfoList);
  49. callShellMethod("setUltr3DData", [ultra3DParameter.toJson()]);
  50. }
  51. }
  52. /// [Carotid] ✅通知 shell 切换到当前所选模型,本质调用了同一个接口
  53. void notifyShellSetCurModel() {
  54. final Ultr3DParameter ultra3DParameter =
  55. Ultr3DParameter(_recordId, [Ultra3DResourceInfo(_carotidResult)]);
  56. callShellMethod("setUltr3DData", [ultra3DParameter.toJson()]);
  57. }
  58. /// [Carotid] ✅shell 通知 webview 切换到当前所选模型
  59. void handleMdlFileLoaded(String loadedMdlFile) {
  60. if (loadedMdlFile == carotidResult.mdlFile) {
  61. onShellLoadedMdlFile.emit(this, null);
  62. }
  63. }
  64. /// [Carotid] ✅shell 通知 flutter 修改测量中的颈动脉2D图像
  65. void handleUpdateCarotid2DImage(String base64Image) {
  66. if (curMeasureMode == MeasureMode.carotid2DMode) {
  67. onUpdateCarotid2DImage.emit(this, base64Image);
  68. }
  69. }
  70. var onUpdateCarotid2DImage = FEventHandler<String>();
  71. /// [Carotid] ✅模型切换时初始化一些参数
  72. void initParams() {
  73. enable2DMeasure = false;
  74. }
  75. @override
  76. CarotidResultDTO get carotidResult => _carotidResult;
  77. @override
  78. var updatePlayerMode = FEventHandler<MeasureMode>();
  79. @override
  80. var onShellLoadedMdlFile = FEventHandler<void>();
  81. var adjustPlaneImage = FEventHandler<ImageAdjustPara>();
  82. @override
  83. set carotidResult(CarotidResultDTO value) {
  84. if (value != _carotidResult) {
  85. _carotidResult = value;
  86. }
  87. }
  88. @override
  89. bool get exist3DData => _exist3DData;
  90. @override
  91. set exist3DData(bool value) {
  92. if (value != _exist3DData) {
  93. _exist3DData = value;
  94. }
  95. }
  96. @override
  97. bool get enable2DMeasure => _enable2DMeasure;
  98. @override
  99. set enable2DMeasure(bool value) {
  100. if (value != _enable2DMeasure) {
  101. _enable2DMeasure = value;
  102. }
  103. }
  104. @override
  105. VidUsImage? get image4Measure => _image4Measure;
  106. @override
  107. set image4Measure(VidUsImage? value) {
  108. if (value != _image4Measure) {
  109. _image4Measure = value;
  110. }
  111. }
  112. @override
  113. String get recordId => _recordId;
  114. @override
  115. set recordId(String value) {
  116. if (value != _recordId) {
  117. _recordId = value;
  118. }
  119. }
  120. @override
  121. List<Ultra3DResourceInfo> get ultra3DResourceInfoList =>
  122. _ultra3DResourceInfoList;
  123. @override
  124. set ultra3DResourceInfoList(List<Ultra3DResourceInfo> value) {
  125. if (value != _ultra3DResourceInfoList) {
  126. _ultra3DResourceInfoList = value;
  127. }
  128. }
  129. @override
  130. MeasureMode get curMeasureMode => _curMeasureMode;
  131. @override
  132. set curMeasureMode(MeasureMode value) {
  133. if (value != _curMeasureMode) {
  134. _curMeasureMode = value;
  135. }
  136. }
  137. /// 当前3D模型切面的亮度、对比度、锐度 :初始值、最大值、最小值、标准值
  138. /// 控件传入的值范围都是 -100 ~ 100 需要手动转换
  139. int _sharpness = 0; //0,200,-200,0
  140. int _brightness = 0; //0,255,-255,0
  141. int _contrast = 100; //100,400,0,100
  142. int get sharpness => _sharpness;
  143. set sharpness(int value) {
  144. _sharpness = value * 2;
  145. }
  146. int get brightness => _brightness;
  147. set brightness(int value) {
  148. _brightness = (value * 2.55).toInt();
  149. }
  150. int get contrast => _contrast;
  151. set contrast(int value) {
  152. if (value <= 0) {
  153. _contrast = value + 100;
  154. } else {
  155. _contrast = value * 3 + 100;
  156. }
  157. }
  158. var onResetTone = FEventHandler<void>();
  159. /// 重置图像增益
  160. void resetTone() {
  161. sharpness = 0;
  162. brightness = 0;
  163. contrast = 0;
  164. notifyShellSetTone();
  165. onResetTone.emit(this, null);
  166. }
  167. ImageAdjustPara curImageAdjustPara =
  168. ImageAdjustPara(brightness: 0, contrast: 100, sharpness: 0);
  169. /// [Carotid] ✅通知 shell 设置图像增益,并且直接调整 webview 中的图像增益, 如果在2D测量模式下,则刷新图像
  170. void notifyShellSetTone() {
  171. //如果参数没变,不刷新
  172. if (sharpness == curImageAdjustPara.sharpness &&
  173. brightness == curImageAdjustPara.brightness &&
  174. contrast == curImageAdjustPara.contrast) {
  175. return;
  176. }
  177. final ImageAdjustPara params = ImageAdjustPara(
  178. brightness: brightness, contrast: contrast, sharpness: sharpness);
  179. curImageAdjustPara = params;
  180. adjustPlaneImage.emit(this, params);
  181. if (curMeasureMode == MeasureMode.carotid2DMode) {
  182. callShellMethod("getCurrentPlaneWithGivenPara", [params.toJson()]);
  183. }
  184. }
  185. }
  186. /// Shell 内的增益调整参数模型
  187. class ImageAdjustPara {
  188. int brightness;
  189. int contrast;
  190. int sharpness;
  191. ImageAdjustPara(
  192. {required this.brightness,
  193. required this.contrast,
  194. required this.sharpness});
  195. String toJson() {
  196. return json.encode({
  197. "Brightness": brightness,
  198. "Contrast": contrast,
  199. "Sharpness": sharpness,
  200. });
  201. }
  202. }
  203. ///获取图片尺寸
  204. Future<Size> loadImageSize(String url) async {
  205. ui.Image image = await getImage(url);
  206. final width = image.width;
  207. final height = image.height;
  208. image.dispose();
  209. return Size(width.toDouble(), height.toDouble());
  210. }
  211. Future<ui.Image> getImage(String path) async {
  212. var completer = Completer<ImageInfo>();
  213. var img = NetworkImage(path);
  214. img
  215. .resolve(const ImageConfiguration())
  216. .addListener(ImageStreamListener((info, _) {
  217. completer.complete(info);
  218. }));
  219. ImageInfo imageInfo = await completer.future;
  220. return imageInfo.image;
  221. }