import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart'; import '../index.dart'; class FaceBoundingBox extends GetView { const FaceBoundingBox({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Obx(() { if (!controller.state.isShowFaceRecognitionResult) { return Container(); } return Container( padding: const EdgeInsets.all(10), child: GetBuilder( id: 'face_bounding_box', builder: (context) { return CustomPaint( size: Size.infinite, painter: _FaceBoundingBoxPainter( faces: controller.kFrameFacesResult, sourceImageSize: controller.kFrameImageSize, isMirror: true, ), ); }), ); }); } } class _FaceBoundingBoxPainter extends CustomPainter { final List faces; /// 是否镜像 final bool isMirror; /// 原始图片大小 final Size sourceImageSize; _FaceBoundingBoxPainter( {required this.faces, required this.isMirror, required this.sourceImageSize}); @override void paint(Canvas canvas, Size size) { // 根据原始图片大小和当前画布大小,计算缩放比例 final scaleX = size.width / sourceImageSize.width; final scaleY = size.height / sourceImageSize.height; if (isMirror) { canvas.scale(-scaleX, scaleY); canvas.translate(-sourceImageSize.width, 0); } else { canvas.scale(scaleX, scaleY); canvas.translate(0, 0); } for (final face in faces) { /// 绘制关键点 // for (final FaceContour? contour in face.contours.values) { // if (contour == null) continue; // if (contour.points.isEmpty) continue; // if (contour.type == FaceContourType.face) { // // _drawContourPointsPath(canvas, size, contour.points); // } else { // // _drawContourPoints(canvas, size, contour.points); // } // } /// 绘制人脸框 _drawFaceRect(canvas, size, face.boundingBox); } /// 全屏画绿色 // final paint2 = Paint() // ..color = const Color.fromARGB(255, 36, 255, 36) // ..strokeWidth = 5 // ..style = PaintingStyle.stroke; // canvas.drawRect( // Rect.fromLTWH(0, 0, sourceImageSize.width, sourceImageSize.height), // paint2, // ); } /// 绘制contour连线 void _drawContourPointsPath( Canvas canvas, Size size, List> points) { final paint = Paint() ..color = Colors.green ..strokeWidth = 4 ..style = PaintingStyle.stroke; final path = Path(); for (int i = 0; i < points.length; i++) { final point = points[i]; if (i == 0) { path.moveTo( point.x.toDouble(), point.y.toDouble(), ); continue; } path.lineTo( point.x.toDouble(), point.y.toDouble(), ); } path.close(); canvas.drawPath(path, paint); } /// 绘制contour点集 void _drawContourPoints(Canvas canvas, Size size, List> points) { final paint = Paint() ..color = Colors.red ..strokeWidth = 2 ..style = PaintingStyle.fill; for (final point in points) { canvas.drawCircle( Offset( point.x.toDouble(), point.y.toDouble(), ), 2, paint, ); } } /// 绘制人脸框 void _drawFaceRect(Canvas canvas, Size size, Rect rect) { final paint = Paint() ..color = Colors.green ..strokeWidth = 3 ..style = PaintingStyle.stroke; canvas.drawRect(rect, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => true; }