detectAndCrop method
Future<Image?>
detectAndCrop(
- CameraImage cameraImage,
- InputImageRotation rotation,
- FaceDetector detector, {
- CameraController? cameraController,
Detects faces in the camera image, applies rotation, and crops the face region.
This method takes into account platform-specific rotations, especially for iOS, where the front camera needs additional rotation adjustments. It selects the largest face in the frame and returns the cropped face image.
Implementation
Future<img.Image?> detectAndCrop(
CameraImage cameraImage,
InputImageRotation rotation,
FaceDetector detector, {
CameraController? cameraController,
}) async {
final inputImage = buildInputImage(cameraImage, rotation);
final faces = await detector.processImage(inputImage);
if (faces.isEmpty) return null;
img.Image fullImage = toImgImage(cameraImage);
final cropRotation = cameraController != null
? getImageRotationForCrop(cameraController)
: rotation;
if (Platform.isIOS) {
fullImage = img.flipHorizontal(fullImage);
} else {
fullImage = _applyRotation(fullImage, cropRotation);
}
final Face bestFace = faces.reduce(
(a, b) => a.boundingBox.width > b.boundingBox.width ? a : b,
);
final box = bestFace.boundingBox;
double left;
final double top = box.top;
final double faceWidth = box.width;
final double faceHeight = box.height;
if (Platform.isIOS) {
left = fullImage.width - box.right;
} else {
left = box.left;
}
const double paddingFactor = 0.0;
final double padX = faceWidth * paddingFactor;
final double padY = faceHeight * paddingFactor;
final x = (left - padX).clamp(0, fullImage.width - 1).toInt();
final y = (top - padY).clamp(0, fullImage.height - 1).toInt();
final w = (faceWidth + padX * 2).clamp(1, fullImage.width - x).toInt();
final h = (faceHeight + padY * 2).clamp(1, fullImage.height - y).toInt();
img.Image cropped = img.copyCrop(
fullImage,
x: x,
y: y,
width: w,
height: h,
);
final int size = cropped.width < cropped.height
? cropped.width
: cropped.height;
final int offsetX = (cropped.width - size) ~/ 2;
final int offsetY = (cropped.height - size) ~/ 2;
cropped = img.copyCrop(
cropped,
x: offsetX,
y: offsetY,
width: size,
height: size,
);
if (Platform.isIOS) {
return _applyRotation(cropped, cropRotation);
}
return cropped;
}