ai_patint.dart 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import 'package:fis_measure/interfaces/date_types/int_size.dart';
  2. import 'package:fis_measure/interfaces/process/player/play_controller.dart';
  3. import 'package:fis_measure/interfaces/process/workspace/application.dart';
  4. import 'package:fis_measure/view/paint/ai_patint_controller.dart';
  5. import 'package:fis_measure/view/paint/parts/dash_line.dart';
  6. import 'package:fis_measure/view/paint/parts/dots.dart';
  7. import 'package:fis_measure/view/paint/parts/rectangle.dart';
  8. import 'package:fis_measure/view/player/controller.dart';
  9. import 'package:fis_measure/view/player/enums.dart';
  10. import 'package:fis_measure/view/player/events.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:get/get.dart';
  13. class AIPaintInfo extends StatefulWidget {
  14. /// 播放器控制器
  15. final VidPlayerController controller;
  16. final double? width;
  17. final double? height;
  18. const AIPaintInfo(
  19. this.controller, {
  20. Key? key,
  21. this.width,
  22. this.height,
  23. }) : super(key: key);
  24. @override
  25. State<AIPaintInfo> createState() => _AIPaintInfoState();
  26. }
  27. class _AIPaintInfoState extends State<AIPaintInfo> {
  28. late final aiPatintController = Get.put(
  29. AiPatintController(
  30. widget.controller,
  31. ),
  32. );
  33. late bool ifShowAiResult;
  34. /// 播放控制器
  35. final playerController = Get.find<IPlayerController>();
  36. @override
  37. void initState() {
  38. //监听Widget是否绘制完毕
  39. super.initState();
  40. widget.controller.eventHandler.addListener(onControllerEvent);
  41. }
  42. @override
  43. void dispose() {
  44. super.dispose();
  45. widget.controller.eventHandler.removeListener(onControllerEvent);
  46. // _removeListenrs();
  47. }
  48. void onControllerEvent(Object sender, VidPlayerEvent e) {
  49. if (e is VidPlayerStatusChangeEvent) {
  50. updateFrame();
  51. aiPatintController.state.vidStatus = e.status;
  52. }
  53. if (e is VidPlayerFrameIndexChangeEvent) {
  54. onFrameChanged(e);
  55. }
  56. if (e is VidPlayerBrightnessChangeEvent) {
  57. updateFrame();
  58. }
  59. if (e is VidPlayerContrastChangeEvent) {
  60. updateFrame();
  61. }
  62. }
  63. void onFrameChanged(VidPlayerFrameIndexChangeEvent e) {
  64. setState(() {
  65. aiPatintController.state.frameIndex = e.index;
  66. });
  67. }
  68. void updateFrame() {
  69. setState(() {});
  70. }
  71. @override
  72. void didUpdateWidget(covariant AIPaintInfo oldWidget) {
  73. if (oldWidget.controller != widget.controller) {
  74. throw UnsupportedError("[VidTestPlayer] unsupport replace controller.");
  75. }
  76. super.didUpdateWidget(oldWidget);
  77. }
  78. @override
  79. Widget build(BuildContext context) {
  80. return Obx(
  81. () {
  82. Widget? child;
  83. switch (aiPatintController.state.vidStatus) {
  84. case VidPlayStatus.init:
  85. child = Container();
  86. break;
  87. case VidPlayStatus.ready:
  88. child = Container();
  89. break;
  90. case VidPlayStatus.loadFail:
  91. child = Container();
  92. break;
  93. case VidPlayStatus.play:
  94. child = LayoutBuilder(builder: (context, constraints) {
  95. try {
  96. ifShowAiResult = aiPatintController.onGetAIResultsInfo();
  97. } catch (e) {
  98. ifShowAiResult = true;
  99. }
  100. if (!ifShowAiResult) {
  101. return const SizedBox();
  102. } else {
  103. return CustomMultiChildLayout(
  104. delegate: _LayerLayoutDelegate(),
  105. children: [
  106. LayoutId(
  107. id: _LayerLayoutIds.rectangle,
  108. child: CustomPaint(
  109. painter: PaintAIRectangle(
  110. aiPatintController.left,
  111. aiPatintController.top,
  112. aiPatintController.width,
  113. aiPatintController.height,
  114. ),
  115. ),
  116. )
  117. ],
  118. );
  119. }
  120. });
  121. break;
  122. case VidPlayStatus.pause:
  123. child = LayoutBuilder(builder: (context, constraints) {
  124. if (!aiPatintController.onGetAIResultsInfo()) {
  125. return const SizedBox();
  126. } else {
  127. return CustomMultiChildLayout(
  128. delegate: _LayerLayoutDelegate(),
  129. children: [
  130. LayoutId(
  131. id: _LayerLayoutIds.dots,
  132. child: Stack(
  133. children: aiPatintController.aiDotsResultsList
  134. .map(
  135. (e) => Obx(
  136. () {
  137. return CustomPaint(
  138. painter: PaintAIDots(
  139. e,
  140. aiPatintController.state.aiResultIndex,
  141. ),
  142. );
  143. },
  144. ),
  145. )
  146. .toList(),
  147. ),
  148. ),
  149. LayoutId(
  150. id: _LayerLayoutIds.dashLine,
  151. child: Stack(
  152. children: aiPatintController.aiDotsResultsList
  153. .map(
  154. (e) => CustomPaint(
  155. painter: PaintAIDashLine(
  156. e,
  157. ),
  158. ),
  159. )
  160. .toList(),
  161. ),
  162. ),
  163. ],
  164. );
  165. }
  166. });
  167. break;
  168. case VidPlayStatus.stop:
  169. case VidPlayStatus.dispose:
  170. child = Container(child: const Text("Closed"));
  171. break;
  172. }
  173. return buildBox(context, child);
  174. },
  175. );
  176. }
  177. Widget buildBox(BuildContext context, Widget child) {
  178. if (aiPatintController.state.ifShowAi) {
  179. return Container(
  180. alignment: Alignment.center,
  181. child: child,
  182. );
  183. } else {
  184. return const SizedBox();
  185. }
  186. }
  187. }
  188. class _LayerLayoutDelegate extends MultiChildLayoutDelegate {
  189. Offset? layoutOffset;
  190. Size? layoutSize;
  191. _LayerLayoutDelegate();
  192. @override
  193. void performLayout(Size size) {
  194. final application = Get.find<IApplication>();
  195. final vidFrame = application.frameData;
  196. final imageSize = IntSize.fill(vidFrame?.width ?? 0, vidFrame?.height ?? 0);
  197. /// 以Contain方式填充布局,计算定位偏移量
  198. calcSize(size, imageSize);
  199. final offset = layoutOffset!;
  200. final renderSize = layoutSize!;
  201. /// 同步图像显示尺寸
  202. application.displaySize = renderSize;
  203. /// 其他层按播放器尺寸位置层叠布局
  204. layoutLayer(_LayerLayoutIds.dots, offset, renderSize);
  205. layoutLayer(_LayerLayoutIds.dashLine, offset, renderSize);
  206. layoutLayer(_LayerLayoutIds.rectangle, offset, renderSize);
  207. layoutLayer(_LayerLayoutIds.aiResult, offset, renderSize);
  208. }
  209. void layoutLayer(_LayerLayoutIds layoutId, Offset offset, Size size) {
  210. if (hasChild(layoutId)) {
  211. layoutChild(
  212. layoutId,
  213. BoxConstraints.loose(size),
  214. );
  215. positionChild(layoutId, offset);
  216. }
  217. }
  218. void calcSize(Size size, IntSize imageSize) {
  219. final parentWHRatio = size.width / size.height;
  220. final imageWHRatio = imageSize.width / imageSize.height;
  221. if (imageWHRatio < parentWHRatio) {
  222. // 高度撑满
  223. final layoutWidth = size.height * imageWHRatio;
  224. final layoutHeight = size.height;
  225. final offsetX = (size.width - layoutWidth) / 2;
  226. layoutOffset = Offset(offsetX, 0);
  227. layoutSize = Size(layoutWidth, layoutHeight);
  228. } else if (imageWHRatio > parentWHRatio) {
  229. // 宽度撑满
  230. final layoutWidth = size.width;
  231. final layoutHeight = size.width / imageWHRatio;
  232. final offsetY = (size.height - layoutHeight) / 2;
  233. layoutOffset = Offset(0, offsetY);
  234. layoutSize = Size(layoutWidth, layoutHeight);
  235. } else {
  236. layoutOffset = Offset.zero;
  237. layoutSize = size;
  238. }
  239. }
  240. @override
  241. bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) {
  242. return false;
  243. }
  244. }
  245. enum _LayerLayoutIds {
  246. ///
  247. dots,
  248. /// 虚线
  249. dashLine,
  250. /// 矩形
  251. rectangle,
  252. /// ai结果
  253. aiResult
  254. }