view.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import 'package:camera/camera.dart';
  2. import 'package:fis_jsonrpc/rpc.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:get/get.dart';
  5. import 'package:vitalapp/architecture/utils/advance_debounce.dart';
  6. import 'package:vitalapp/components/appbar.dart';
  7. import 'controller_plus.dart';
  8. import 'index.dart';
  9. import 'widgets/widgets.dart';
  10. class FacialRecognitionPage extends GetView<FacialRecognitionController> {
  11. const FacialRecognitionPage({
  12. Key? key,
  13. required this.mode,
  14. this.patientInfo,
  15. }) : super(key: key);
  16. final FacialRecognitionMode mode;
  17. final PatientDTO? patientInfo;
  18. @override
  19. Widget build(BuildContext context) {
  20. return GetBuilder<FacialRecognitionController>(
  21. init: FacialRecognitionControllerPlus(
  22. mode: mode,
  23. patientInfo: patientInfo,
  24. ),
  25. builder: (_) {
  26. return Scaffold(
  27. appBar: VAppBar(
  28. titleText:
  29. mode == FacialRecognitionMode.faceInput ? "人像采集" : "人脸识别",
  30. ),
  31. body: SafeArea(
  32. child: Obx(
  33. () => controller.state.isCameraReady
  34. ? _buildCameraArea()
  35. : const Center(
  36. child: CircularProgressIndicator(
  37. valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
  38. ),
  39. ),
  40. ),
  41. ),
  42. );
  43. },
  44. );
  45. }
  46. Widget _buildCameraArea() {
  47. return Row(
  48. children: [
  49. Expanded(
  50. child: ClipRRect(
  51. child: LayoutBuilder(builder: (context, constraints) {
  52. return Stack(
  53. children: <Widget>[
  54. OverflowBox(
  55. maxHeight: constraints.maxHeight,
  56. maxWidth: 2000,
  57. child: Container(
  58. color: Colors.black,
  59. child: Center(
  60. child: _cameraPreviewWidget(),
  61. ),
  62. ),
  63. ),
  64. const Center(child: CameraForFace()),
  65. Align(
  66. alignment: Alignment.bottomRight,
  67. child: _switchCameraLens(),
  68. ),
  69. const ImageDetectingDialog(),
  70. ],
  71. );
  72. }),
  73. ),
  74. ),
  75. ],
  76. );
  77. }
  78. /// 相机预览
  79. Widget _cameraPreviewWidget() {
  80. final CameraController? cameraController = controller.kCameraController;
  81. if (cameraController == null || !cameraController.value.isInitialized) {
  82. /// 旋转loading
  83. return const Center(
  84. child: CircularProgressIndicator(),
  85. );
  86. } else {
  87. return Listener(
  88. onPointerDown: (_) => controller.pointers++,
  89. onPointerUp: (_) => controller.pointers--,
  90. child: CameraPreview(
  91. cameraController,
  92. child: LayoutBuilder(
  93. builder: (BuildContext context, BoxConstraints constraints) {
  94. return GestureDetector(
  95. behavior: HitTestBehavior.opaque,
  96. onScaleStart: controller.handleScaleStart,
  97. onScaleUpdate: controller.handleScaleUpdate,
  98. onTapDown: (TapDownDetails details) =>
  99. controller.onViewFinderTap(details, constraints),
  100. child: const FaceBoundingBox(),
  101. );
  102. },
  103. ),
  104. ),
  105. );
  106. }
  107. }
  108. Widget _switchCameraLens() {
  109. return Obx(() {
  110. if (controller.state.isRunningFaceRecognition) {
  111. return Container();
  112. }
  113. return GestureDetector(
  114. onTap: () {
  115. advanceDebounce(controller.switchCameraLens, "capture", 1500);
  116. },
  117. child: Container(
  118. padding: const EdgeInsets.all(10.0),
  119. // padding: const EdgeInsets.all(10),
  120. decoration: BoxDecoration(
  121. color: Colors.black.withOpacity(0.2),
  122. borderRadius: BorderRadius.circular(10),
  123. ),
  124. margin: const EdgeInsets.symmetric(horizontal: 40.0, vertical: 20.0),
  125. child: Column(
  126. mainAxisSize: MainAxisSize.min,
  127. children: [
  128. const Icon(
  129. Icons.camera_rear,
  130. size: 30,
  131. color: Colors.white,
  132. ),
  133. const SizedBox(height: 10),
  134. Text(
  135. controller.state.isUsingFrontCamera ? "切换为后置" : "切换为前置",
  136. style: const TextStyle(color: Colors.white),
  137. )
  138. ],
  139. ),
  140. ),
  141. );
  142. });
  143. }
  144. }