import 'package:camera/camera.dart'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:vitalapp/architecture/app_parameters.dart'; import 'package:vitalapp/architecture/utils/advance_debounce.dart'; import 'package:vitalapp/components/appbar.dart'; import 'controller_plus.dart'; import 'index.dart'; import 'widgets/widgets.dart'; class FacialRecognitionPage extends GetView { const FacialRecognitionPage({ Key? key, required this.mode, this.patientInfo, this.isVital, }) : super(key: key); final FacialRecognitionMode mode; final PatientDTO? patientInfo; final bool? isVital; @override Widget build(BuildContext context) { return GetBuilder( init: FacialRecognitionControllerPlus( mode: mode, patientInfo: patientInfo, isVital: isVital), builder: (_) { return Scaffold( appBar: VAppBar( titleText: mode == FacialRecognitionMode.faceInput ? "绑定人脸" : "人脸识别", ), body: SafeArea( child: Obx( () => controller.state.isCameraReady ? Container( color: Colors.black, child: _buildCameraArea(), ) : const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Colors.blue), ), ), ), ), ); }, ); } Widget _buildCameraArea() { return Row( children: [ Expanded( child: ClipRRect( child: LayoutBuilder(builder: (context, constraints) { return Stack( children: [ OverflowBox( child: AspectRatio( aspectRatio: controller.kCameraController?.value.aspectRatio ?? 1, child: _cameraPreviewWidget(), ), ), const Center(child: CameraForFace()), Align( alignment: Alignment.bottomRight, child: _switchCameraLens(), ), const ImageDetectingDialog(), ], ); }), ), ), ], ); } /// 相机预览 Widget _cameraPreviewWidget() { final CameraController? cameraController = controller.kCameraController; if (cameraController == null || !cameraController.value.isInitialized) { /// 旋转loading return const Center( child: CircularProgressIndicator(), ); } else { return Listener( onPointerDown: (_) => controller.pointers++, onPointerUp: (_) => controller.pointers--, child: CameraPreview( cameraController, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return GestureDetector( behavior: HitTestBehavior.opaque, onScaleStart: controller.handleScaleStart, onScaleUpdate: controller.handleScaleUpdate, onTapDown: (TapDownDetails details) => controller.onViewFinderTap(details, constraints), child: const FaceBoundingBox(), ); }, ), ), ); } } Widget _switchCameraLens() { return Obx(() { if (controller.state.isRunningFaceRecognition) { return Container(); } if (AppParameters.data.isLocalStation) { return Container(); } return GestureDetector( onTap: () { advanceDebounce(controller.switchCameraLens, "capture", 1500); }, child: Container( padding: const EdgeInsets.all(10.0), // padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.black.withOpacity(0.2), borderRadius: BorderRadius.circular(10), ), margin: const EdgeInsets.symmetric(horizontal: 40.0, vertical: 20.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.camera_rear, size: 30, color: Colors.white, ), const SizedBox(height: 10), Text( controller.state.isUsingFrontCamera ? "切换为后置" : "切换为前置", style: const TextStyle(color: Colors.white), ) ], ), ), ); }); } }