import 'package:body_detection/models/pose.dart'; import 'package:body_detection/models/pose_landmark.dart'; import 'package:body_detection/models/pose_landmark_type.dart'; import 'package:flutter/widgets.dart'; class PosePainter extends CustomPainter { final Pose? pose; final Size imageSize; PosePainter({required this.pose, required this.imageSize, Key? key}); final pointPaint = Paint()..color = const Color.fromRGBO(255, 255, 255, 0.8); final leftPointPaint = Paint()..color = const Color.fromRGBO(223, 157, 80, 1); final rightPointPaint = Paint()..color = const Color.fromRGBO(100, 208, 218, 1); final linePaint = Paint() ..color = const Color.fromARGB(228, 0, 0, 0) ..strokeWidth = 3; @override void paint(Canvas canvas, Size size) { if (pose == null) return; final double hRatio = imageSize.width == 0 ? 1 : size.width / imageSize.width; final double vRatio = imageSize.height == 0 ? 1 : size.height / imageSize.height; offsetForPart(PoseLandmark part) => Offset(part.position.x * hRatio, part.position.y * vRatio); // Landmark connections final landmarksByType = {for (final it in pose!.landmarks) it.type: it}; for (final connection in connections) { if (landmarksByType[connection[0]] != null && landmarksByType[connection[1]] != null) { final point1 = offsetForPart(landmarksByType[connection[0]]!); final point2 = offsetForPart(landmarksByType[connection[1]]!); canvas.drawLine(point1, point2, linePaint); } } // for (final part in pose!.landmarks) { // // Landmark points // canvas.drawCircle(offsetForPart(part), 5, pointPaint); // if (part.type.isLeftSide) { // canvas.drawCircle(offsetForPart(part), 3, leftPointPaint); // } else if (part.type.isRightSide) { // canvas.drawCircle(offsetForPart(part), 3, rightPointPaint); // } // // Landmark labels // TextSpan span = TextSpan( // text: part.type.toString().substring(16), // style: const TextStyle( // color: Color.fromRGBO(0, 128, 255, 1), // fontSize: 10, // shadows: [ // Shadow( // color: Color.fromRGBO(255, 255, 255, 1), // offset: Offset(1, 1), // blurRadius: 1, // ), // ], // ), // ); // TextPainter tp = TextPainter(text: span, textAlign: TextAlign.left); // tp.textDirection = TextDirection.ltr; // tp.layout(); // tp.paint(canvas, offsetForPart(part)); // } } @override bool shouldRepaint(PosePainter oldDelegate) { return oldDelegate.pose != pose || oldDelegate.imageSize != imageSize; } static const List> connections = [ // [PoseLandmarkType.leftEar, PoseLandmarkType.leftEyeOuter], // [PoseLandmarkType.leftEyeOuter, PoseLandmarkType.leftEye], // [PoseLandmarkType.leftEye, PoseLandmarkType.leftEyeInner], // [PoseLandmarkType.leftEyeInner, PoseLandmarkType.nose], // [PoseLandmarkType.nose, PoseLandmarkType.rightEyeInner], // [PoseLandmarkType.rightEyeInner, PoseLandmarkType.rightEye], // [PoseLandmarkType.rightEye, PoseLandmarkType.rightEyeOuter], // [PoseLandmarkType.rightEyeOuter, PoseLandmarkType.rightEar], // [PoseLandmarkType.mouthLeft, PoseLandmarkType.mouthRight], [PoseLandmarkType.leftShoulder, PoseLandmarkType.rightShoulder], [PoseLandmarkType.leftShoulder, PoseLandmarkType.leftHip], [PoseLandmarkType.rightShoulder, PoseLandmarkType.rightHip], [PoseLandmarkType.rightShoulder, PoseLandmarkType.rightElbow], [PoseLandmarkType.rightWrist, PoseLandmarkType.rightElbow], // [PoseLandmarkType.rightWrist, PoseLandmarkType.rightThumb], // [PoseLandmarkType.rightWrist, PoseLandmarkType.rightIndexFinger], // [PoseLandmarkType.rightWrist, PoseLandmarkType.rightPinkyFinger], [PoseLandmarkType.leftHip, PoseLandmarkType.rightHip], [PoseLandmarkType.leftHip, PoseLandmarkType.leftKnee], [PoseLandmarkType.rightHip, PoseLandmarkType.rightKnee], [PoseLandmarkType.rightKnee, PoseLandmarkType.rightAnkle], [PoseLandmarkType.leftKnee, PoseLandmarkType.leftAnkle], [PoseLandmarkType.leftElbow, PoseLandmarkType.leftShoulder], [PoseLandmarkType.leftWrist, PoseLandmarkType.leftElbow], // [PoseLandmarkType.leftWrist, PoseLandmarkType.leftThumb], // [PoseLandmarkType.leftWrist, PoseLandmarkType.leftIndexFinger], // [PoseLandmarkType.leftWrist, PoseLandmarkType.leftPinkyFinger], // [PoseLandmarkType.leftAnkle, PoseLandmarkType.leftHeel], // [PoseLandmarkType.leftAnkle, PoseLandmarkType.leftToe], // [PoseLandmarkType.rightAnkle, PoseLandmarkType.rightHeel], // [PoseLandmarkType.rightAnkle, PoseLandmarkType.rightToe], // [PoseLandmarkType.rightHeel, PoseLandmarkType.rightToe], // [PoseLandmarkType.leftHeel, PoseLandmarkType.leftToe], // [PoseLandmarkType.rightIndexFinger, PoseLandmarkType.rightPinkyFinger], // [PoseLandmarkType.leftIndexFinger, PoseLandmarkType.leftPinkyFinger], ]; }