flutter_facelytical
A powerful Flutter plugin for real-time face detection and capture using native Android (Jetpack Compose + CameraX) and iOS (SwiftUI + AVFoundation) implementations. Perfect for authentication, identity verification, and face capture applications.
β¨ Features
- π― Real-time face detection with ML Kit (Android) and Vision (iOS)
- πΈ High-quality face capture with automatic cropping
- π¨ Native UI built with Jetpack Compose (Android) and SwiftUI (iOS)
- π Privacy-focused - all processing happens on-device
- β‘ Optimized performance with native camera implementations
- π Face framing guidance with visual feedback
- π± Cross-platform support for Android and iOS
π Installation
Add this to your package's pubspec.yaml
file:
dependencies:
flutter_facelytical: ^0.0.1
Then run:
flutter pub get
π± Platform Setup
Android Setup
-
Minimum Requirements:
- Target SDK: 35 or above
- Minimum SDK: 21
-
Update
android/app/build.gradle
:android { compileSdkVersion 35 targetSdkVersion 35 minSdkVersion 21 }
-
Add permissions in
android/app/src/main/AndroidManifest.xml
:<uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-permission android:name="android.permission.CAMERA"/>
iOS Setup
-
Minimum Requirements:
- iOS 15.0 or above
-
Update
ios/Podfile
:platform :ios, '15.0'
-
Add camera permission in
ios/Runner/Info.plist
:<key>NSCameraUsageDescription</key> <string>This app needs camera access to detect and capture your face for authentication purposes.</string>
π Usage
Basic Implementation
import 'package:flutter/material.dart';
import 'package:flutter_facelytical/flutter_facelytical.dart';
import 'dart:convert';
class FaceDetectionPage extends StatefulWidget {
@override
_FaceDetectionPageState createState() => _FaceDetectionPageState();
}
class _FaceDetectionPageState extends State<FaceDetectionPage> {
final _flutterFacelytical = FlutterFacelytical();
String? _capturedImageBase64;
bool _hasCameraPermission = false;
@override
void initState() {
super.initState();
_checkCameraPermission();
}
Future<void> _checkCameraPermission() async {
final hasPermission = await _flutterFacelytical.hasCameraPermission();
setState(() {
_hasCameraPermission = hasPermission;
});
}
Future<void> _requestCameraPermission() async {
final granted = await _flutterFacelytical.requestCameraPermission();
setState(() {
_hasCameraPermission = granted;
});
}
Future<void> _detectFace() async {
try {
final imageBase64 = await _flutterFacelytical.presentFaceDetection();
if (imageBase64 != null) {
setState(() {
_capturedImageBase64 = imageBase64.replaceAll('\n', '');
});
// Process the captured face image
_processCapturedFace(_capturedImageBase64!);
}
} catch (e) {
_showError('Face detection failed: $e');
}
}
void _processCapturedFace(String base64Image) {
// Your face processing logic here
print('Face captured successfully!');
}
void _showError(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Face Detection')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
// Permission status
Text(
'Camera Permission: ${_hasCameraPermission ? "Granted" : "Not Granted"}',
style: TextStyle(fontSize: 16),
),
SizedBox(height: 20),
// Permission button
if (!_hasCameraPermission)
ElevatedButton(
onPressed: _requestCameraPermission,
child: Text('Grant Camera Permission'),
),
// Face detection button
if (_hasCameraPermission)
ElevatedButton(
onPressed: _detectFace,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 24),
),
child: Text('Start Face Detection'),
),
SizedBox(height: 20),
// Captured image display
if (_capturedImageBase64 != null)
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.memory(
base64Decode(_capturedImageBase64!),
fit: BoxFit.contain,
),
),
),
),
],
),
),
);
}
}
π§ API Reference
FlutterFacelytical
Methods
getPlatformVersion()
Returns the platform version information.
String? version = await flutterFacelytical.getPlatformVersion();
hasCameraPermission()
Checks if camera permission is granted.
bool hasPermission = await flutterFacelytical.hasCameraPermission();
requestCameraPermission()
Requests camera permission from the user.
bool granted = await flutterFacelytical.requestCameraPermission();
presentFaceDetection()
Opens the face detection interface and returns the captured face as a base64 string.
String? base64Image = await flutterFacelytical.presentFaceDetection();
Return Values
- Success: Returns a base64-encoded string of the captured face image
- User Cancellation: Returns
null
- Error: Throws
PlatformException
with error details
Error Codes
Code | Description |
---|---|
PERMISSION_DENIED |
Camera permission not granted |
CAPTURE_ERROR |
Error during face capture |
CANCELLED |
User cancelled the operation |
NO_ACTIVITY |
No activity available (Android) |
CONVERSION_ERROR |
Failed to convert image to base64 |
π― Use Cases
- Identity Verification: Capture faces for KYC processes
- Authentication: Face-based login systems
- Profile Pictures: High-quality face capture for user profiles
- Security: Access control with face recognition
- Healthcare: Patient identification systems
- Education: Student verification for online exams
β οΈ Error Handling
Future<void> _handleFaceDetection() async {
try {
final result = await _flutterFacelytical.presentFaceDetection();
if (result != null) {
// Success - process the captured face
_processImage(result);
} else {
// User cancelled
_showMessage('Face capture was cancelled');
}
} on PlatformException catch (e) {
switch (e.code) {
case 'PERMISSION_DENIED':
_showError('Camera permission is required');
break;
case 'CAPTURE_ERROR':
_showError('Failed to capture face: ${e.message}');
break;
case 'CANCELLED':
_showMessage('Face capture cancelled');
break;
default:
_showError('Unknown error: ${e.message}');
}
}
}
π Requirements
Android
- Android 5.0 (API level 21) or higher
- Camera hardware
- Sufficient storage space for temporary image processing
iOS
- iOS 15.0 or higher
- Camera access
- Sufficient storage space for temporary image processing
π Privacy & Security
- On-device Processing: All face detection and processing happens locally on the device
- No Data Collection: The plugin does not collect or transmit any personal data
- Temporary Storage: Images are processed in memory and not permanently stored
- Permission-based: Requires explicit user permission for camera access
π¨ UI Features
- Real-time Face Detection: Live feedback when face is detected
- Visual Guide: Face frame overlay to guide users
- Capture Feedback: Visual and audio feedback on successful capture
- Error Handling: Clear error messages and recovery options
- Native Look: Follows platform design guidelines
π Troubleshooting
Common Issues
-
Camera Permission Issues
- Ensure proper permissions are declared in platform manifests
- Request permissions before using face detection
-
Build Errors on Android
- Verify target SDK is 35 or above
- Check that camera permissions are properly declared
-
iOS Build Issues
- Ensure iOS deployment target is 15.0 or above
- Verify camera usage description is added to Info.plist
-
Face Detection Not Working
- Ensure good lighting conditions
- Check that the device camera is functioning properly
- Verify that face is properly positioned within the frame
Performance Tips
- Test on actual devices rather than simulators for best performance
- Ensure good lighting conditions for optimal face detection
- Close the face detection interface when not needed to preserve battery
π License
This project is licensed under the MIT License - see the LICENSE file for details.
π€ Contributing
We welcome contributions! Please feel free to submit issues and enhancement requests.
π Support
For support and questions, please create an issue in the repository or contact the development team.