import 'dart:convert'; import 'package:fis_measure/interfaces/process/player/play_controller.dart'; import 'package:fis_measure/interfaces/process/workspace/application.dart'; import 'package:fis_measure/process/workspace/measure_data_controller.dart'; import 'package:fis_measure/view/paint/ai_patint_state.dart'; import 'package:fis_measure/view/paint/date_structure.dart'; import 'package:fis_measure/view/player/controller.dart'; import 'package:fis_measure/view/player/enums.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; class AiPatintController extends GetxController { static const _HAS_VIEW_STATUS_ARR = [VidPlayStatus.play, VidPlayStatus.pause]; /// 播放器控制器 final VidPlayerController controller; final state = AiPatintState(); late final application = Get.find(); /// ai结果 // late final List aiResult = []; /// 测量AI数据 final measureData = Get.find(); /// 播放控制器 final playerController = Get.find(); /// ai结果图展示 late List aiResultsList = []; /// ai结果数据 late List aiDetectedObject = []; /// ai部位 late DiagnosisOrganEnum diagnosisOrgan = DiagnosisOrganEnum.Null; /// 是否是播放状态 get isPlay => playerController.status == VidPlayStatus.play; /// ai json 数据 late String? aiResults = ''; /// ai的横纵坐标 四个点 late Offset p1 = Offset.zero; late Offset p2 = Offset.zero; late Offset p3 = Offset.zero; late Offset p4 = Offset.zero; /// 视频时的画面 double left = -1; double top = -1; double width = -1; double height = -1; /// 当前帧数 int? frameIndex; /// ai结果下标 // int aiResultIndex = 0; AiPatintController(this.controller); @override void onInit() { _addListenrs(); super.onInit(); } void onMeasuredAIResultsInfoChanged(Object sender, String e) { if (e.isNotEmpty && e != "[]") { aiResults = e; final measureDataAIResults = jsonDecode( aiResults ?? '', ); state.aiResult.clear(); for (int i = 0; i < (measureDataAIResults as List).length; i++) { state.aiResult.add( AIDiagnosisPerImageDTO.fromJson( measureDataAIResults[i], ), ); } } else { aiResults = ''; state.aiResult.clear(); } } /// 单帧图处理 void onSingleFrameImage( List? detectedObjects, DiagnosisOrganEnum organ, double widthScale, ) { aiDetectedObject = detectedObjects ?? []; diagnosisOrgan = organ; for (int m = 0; m < detectedObjects!.length; m++) { final List? contours = detectedObjects[m].contours; if (contours!.isNotEmpty && detectedObjects[m].descriptions!.isNotEmpty) { final descriptions = jsonDecode( detectedObjects[m] .descriptions![detectedObjects[m].descriptions!.length - 1] .value!, ); if (_HAS_VIEW_STATUS_ARR .contains((playerController as VidPlayerController).status)) { for (int i = 0; i < contours.length; i++) { if (i % 10 == 0) { aiResultsList.add(Offset( contours[i].x * widthScale, contours[i].y * widthScale, )); } } p1 = Offset(descriptions['HorizontalPoint1']['X'] * widthScale, descriptions['HorizontalPoint1']['Y'] * widthScale); p2 = Offset(descriptions['HorizontalPoint2']['X'] * widthScale, descriptions['HorizontalPoint2']['Y'] * widthScale); p3 = Offset(descriptions['VerticalPoint1']['X'] * widthScale, descriptions['VerticalPoint1']['Y'] * widthScale); p4 = Offset(descriptions['VerticalPoint2']['X'] * widthScale, descriptions['VerticalPoint2']['Y'] * widthScale); } } } } /// ai处理图片结果 bool onGetAIResultsInfo(double widthScale) { if (state.aiResult.isEmpty) { return false; } else if (state.aiResult.length == 1) { final diagResultsForEachOrgan = state.aiResult[0].diagResultsForEachOrgan?[state.aiResultIndex]; final detectedObjects = diagResultsForEachOrgan!.detectedObjects; final diagnosisOrgan = diagResultsForEachOrgan.organ; _updateFeatures(); if (detectedObjects!.isNotEmpty) { onSingleFrameImage( detectedObjects, diagnosisOrgan, widthScale, ); } else { return false; } return true; } else { _updateFeatures(); final diagResultsForEachOrgan = state.aiResult[state.frameIndex!] .diagResultsForEachOrgan![state.aiResultIndex]; final detectedObjects = diagResultsForEachOrgan.detectedObjects; final diagnosisOrgan = diagResultsForEachOrgan.organ; if ((playerController as VidPlayerController).status == VidPlayStatus.pause) { if (detectedObjects!.isNotEmpty) { onSingleFrameImage( detectedObjects, diagnosisOrgan, widthScale, ); } } else if (isPlay) { for (int m = 0; m < detectedObjects!.length; m++) { final organBoundBox = detectedObjects[m].boundingBox; left = organBoundBox!.left * widthScale; top = organBoundBox.top * widthScale; width = organBoundBox.width * widthScale; height = organBoundBox.height * widthScale; } } return true; } } void _updateFeatures() { aiResultsList = []; left = 0; top = 0; width = 0; height = 0; p1 = Offset.zero; p2 = Offset.zero; p3 = Offset.zero; p4 = Offset.zero; } void _onMeasureRerenderReady(Object sender, void e) async { update(); } void _addListenrs() async { application.updateRenderReady.addListener(_onMeasureRerenderReady); measureData.aiResultsInfoChanged .addListener(onMeasuredAIResultsInfoChanged); if (measureData.aiResults.isNotEmpty) { onMeasuredAIResultsInfoChanged(this, measureData.aiResults); } } void _removeListenrs() { application.updateRenderReady.removeListener(_onMeasureRerenderReady); measureData.aiResultsInfoChanged .removeListener(onMeasuredAIResultsInfoChanged); } }