Эх сурвалжийг харах

优化人脸识别处理逻辑

gavin.chen 1 жил өмнө
parent
commit
9a780d9701

+ 10 - 0
lib/pages/facial_recognition/controller.dart

@@ -376,6 +376,7 @@ class FacialRecognitionController extends GetxController
       return;
     }
     final XFile? file = await takePicture();
+    state.processingImageLocalPath = '';
     if (file != null) {
       faceDetector = FaceDetector(options: FaceDetectorOptions());
       // faceDetector =
@@ -395,6 +396,7 @@ class FacialRecognitionController extends GetxController
           PromptBox.toast('上传的图像类型错误');
           return;
         }
+        state.processingImageLocalPath = file.path;
         final url = await rpc.storage.upload(
           file,
           fileType: fileType,
@@ -412,6 +414,7 @@ class FacialRecognitionController extends GetxController
               image: url,
             ),
           );
+          state.processingImageLocalPath = '';
           if (result.faceScanErrorType == FaceScanErrorTypeEnum.Success) {
             finishFaceDetection(result);
           } else if (result.faceScanErrorType ==
@@ -431,7 +434,9 @@ class FacialRecognitionController extends GetxController
           }
         } catch (e) {
           logger.e("getPatientBaseByFaceImageAsync failed: $e", e);
+          state.processingImageLocalPath = '';
         }
+        state.processingImageLocalPath = '';
       }
     }
     doFacialRecognition();
@@ -446,6 +451,7 @@ class FacialRecognitionController extends GetxController
       idCardInfo.idCardNumber = patientInfo!.cardNo!;
     }
     final XFile? file = await takePicture();
+    state.processingImageLocalPath = '';
     if (file != null) {
       faceDetector = FaceDetector(options: FaceDetectorOptions());
       // faceDetector =
@@ -466,6 +472,7 @@ class FacialRecognitionController extends GetxController
         PromptBox.toast('上传的图像类型错误');
         return;
       }
+      state.processingImageLocalPath = file.path;
       final url = await rpc.storage.upload(
         file,
         fileType: fileType,
@@ -484,6 +491,7 @@ class FacialRecognitionController extends GetxController
             image: url,
           ),
         );
+        state.processingImageLocalPath = '';
         if (result.success) {
           Get.back(result: true);
         } else {
@@ -536,8 +544,10 @@ class FacialRecognitionController extends GetxController
           }
         }
       } catch (e) {
+        state.processingImageLocalPath = '';
         logger.e("savePatientBaseByFaceImageAsync failed: $e", e);
       }
+      state.processingImageLocalPath = '';
     }
   }
 

+ 6 - 0
lib/pages/facial_recognition/state.dart

@@ -37,4 +37,10 @@ class FacialRecognitionState {
   set isRunningFaceRecognition(value) =>
       _isRunningFaceRecognition.value = value;
   bool get isRunningFaceRecognition => _isRunningFaceRecognition.value;
+
+  /// 正在处理中的图像的本地路径
+  final _processingImageLocalPath = ''.obs;
+  set processingImageLocalPath(value) =>
+      _processingImageLocalPath.value = value;
+  String get processingImageLocalPath => _processingImageLocalPath.value;
 }

+ 1 - 0
lib/pages/facial_recognition/view.dart

@@ -67,6 +67,7 @@ class FacialRecognitionPage extends GetView<FacialRecognitionController> {
                     alignment: Alignment.bottomRight,
                     child: _switchCameraLens(),
                   ),
+                  const ImageDetectingDialog(),
                 ],
               );
             }),

+ 97 - 0
lib/pages/facial_recognition/widgets/image_detecting_dialog.dart

@@ -0,0 +1,97 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import '../index.dart';
+
+class ImageDetectingDialog extends GetView<FacialRecognitionController> {
+  const ImageDetectingDialog({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Obx(
+      () {
+        if (controller.state.processingImageLocalPath.isEmpty) {
+          return Container();
+        }
+        // 是否需要左右翻转
+        final needMirror = controller.state.isUsingFrontCamera;
+        return Center(
+          child: Stack(
+            children: [
+              ModalBarrier(
+                color: Colors.black.withOpacity(0.5),
+                dismissible: false,
+              ),
+              Center(
+                child: Container(
+                  width: 850,
+                  height: 600,
+                  decoration: BoxDecoration(
+                    color: Colors.white,
+                    borderRadius: BorderRadius.circular(10),
+                  ),
+                  clipBehavior: Clip.antiAlias,
+                  padding: const EdgeInsets.all(40),
+                  child: Column(
+                    children: [
+                      Stack(
+                        children: [
+                          Center(
+                            child: Container(
+                              decoration: BoxDecoration(
+                                borderRadius: BorderRadius.circular(10),
+                              ),
+                              clipBehavior: Clip.antiAlias,
+                              child: Transform(
+                                alignment: Alignment.center,
+                                transform: Matrix4.rotationY(
+                                    needMirror ? 3.1415926 : 0),
+                                child: Image(
+                                  image: FileImage(
+                                    File(controller
+                                        .state.processingImageLocalPath),
+                                  ),
+                                  fit: BoxFit.cover,
+                                ),
+                              ),
+                            ),
+                          ),
+                        ],
+                      ),
+                      const SizedBox(height: 40),
+                      Expanded(
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.center,
+                          children: const [
+                            SizedBox(
+                              height: 20,
+                              width: 20,
+                              child: CircularProgressIndicator(
+                                valueColor:
+                                    AlwaysStoppedAnimation<Color>(Colors.blue),
+                              ),
+                            ),
+                            SizedBox(
+                              width: 20,
+                            ),
+                            Text(
+                              '人脸信息识别中,请稍后...',
+                              style: TextStyle(
+                                  fontSize: 16, color: Colors.black54),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              // 旋转的 loading
+            ],
+          ),
+        );
+      },
+    );
+  }
+}

+ 1 - 0
lib/pages/facial_recognition/widgets/widgets.dart

@@ -2,3 +2,4 @@ library widgets;
 
 export './camera_for_face.dart';
 export './face_bounding_box.dart';
+export './image_detecting_dialog.dart';

+ 6 - 0
lib/pages/id_card_scan/controller.dart

@@ -247,9 +247,11 @@ class IdCardScanController extends GetxController with WidgetsBindingObserver {
   /// 发生拍摄身份证事件
   void onCaptureIdCardButtonPressed() {
     state.isIdCardScanning = true;
+    state.processingImageLocalPath = '';
     takePicture().then((XFile? file) async {
       // imageFile = file;
       if (file != null) {
+        state.processingImageLocalPath = file.path;
         try {
           final String fileType = file.path.split('.').last;
           if (!['png', 'jpg'].contains(fileType)) {
@@ -271,6 +273,9 @@ class IdCardScanController extends GetxController with WidgetsBindingObserver {
               image: url,
             ),
           );
+          state.processingImageLocalPath = '';
+
+          /// 用于关闭 ImageDetectingDialog
           if (result.isSuccess) {
             PromptBox.toast('身份证识别成功');
             final idCardScanResult = IdCardScanResult(
@@ -288,6 +293,7 @@ class IdCardScanController extends GetxController with WidgetsBindingObserver {
           logger.e("getPatientBaseByImageAsync failed: $e", e);
         }
       }
+      state.processingImageLocalPath = '';
       state.isIdCardScanning = false;
     });
   }

+ 6 - 0
lib/pages/id_card_scan/state.dart

@@ -20,4 +20,10 @@ class IdCardScanState {
   final _isUsingFrontCamera = false.obs;
   set isUsingFrontCamera(value) => _isUsingFrontCamera.value = value;
   bool get isUsingFrontCamera => _isUsingFrontCamera.value;
+
+  /// 正在处理中的图像的本地路径
+  final _processingImageLocalPath = ''.obs;
+  set processingImageLocalPath(value) =>
+      _processingImageLocalPath.value = value;
+  String get processingImageLocalPath => _processingImageLocalPath.value;
 }

+ 1 - 0
lib/pages/id_card_scan/view.dart

@@ -57,6 +57,7 @@ class IdCardScanPage extends GetView<IdCardScanController> {
                   const Center(
                     child: CameraForIdCard(),
                   ),
+                  const ImageDetectingDialog(),
                 ],
               );
             }),

+ 90 - 0
lib/pages/id_card_scan/widgets/image_detecting_dialog.dart

@@ -0,0 +1,90 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import '../index.dart';
+
+class ImageDetectingDialog extends GetView<IdCardScanController> {
+  const ImageDetectingDialog({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Obx(
+      () {
+        if (controller.state.processingImageLocalPath.isEmpty) {
+          return Container();
+        }
+        return Center(
+          child: Stack(
+            children: [
+              ModalBarrier(
+                color: Colors.black.withOpacity(0.5),
+                dismissible: false,
+              ),
+              Center(
+                child: Container(
+                  width: 850,
+                  height: 600,
+                  decoration: BoxDecoration(
+                    color: Colors.white,
+                    borderRadius: BorderRadius.circular(10),
+                  ),
+                  clipBehavior: Clip.antiAlias,
+                  padding: const EdgeInsets.all(40),
+                  child: Column(
+                    children: [
+                      Stack(
+                        children: [
+                          Center(
+                            child: Container(
+                              decoration: BoxDecoration(
+                                borderRadius: BorderRadius.circular(10),
+                              ),
+                              clipBehavior: Clip.antiAlias,
+                              child: Image(
+                                image: FileImage(
+                                  File(controller
+                                      .state.processingImageLocalPath),
+                                ),
+                                fit: BoxFit.cover,
+                              ),
+                            ),
+                          ),
+                        ],
+                      ),
+                      const SizedBox(height: 40),
+                      Expanded(
+                        child: Row(
+                          mainAxisAlignment: MainAxisAlignment.center,
+                          children: const [
+                            SizedBox(
+                              height: 20,
+                              width: 20,
+                              child: CircularProgressIndicator(
+                                valueColor:
+                                    AlwaysStoppedAnimation<Color>(Colors.blue),
+                              ),
+                            ),
+                            SizedBox(
+                              width: 20,
+                            ),
+                            Text(
+                              '身份证信息识别中,请稍后...',
+                              style: TextStyle(
+                                  fontSize: 16, color: Colors.black54),
+                            ),
+                          ],
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+              // 旋转的 loading
+            ],
+          ),
+        );
+      },
+    );
+  }
+}

+ 1 - 0
lib/pages/id_card_scan/widgets/widgets.dart

@@ -2,3 +2,4 @@ library widgets;
 
 export './debug_camera.dart';
 export './camera_for_id_card.dart';
+export './image_detecting_dialog.dart';