ai_patint.dart 7.1 KB

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