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

  1. Minimum Requirements:

    • Target SDK: 35 or above
    • Minimum SDK: 21
  2. Update android/app/build.gradle:

    android {
        compileSdkVersion 35
        targetSdkVersion 35
        minSdkVersion 21
    }
    
  3. 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

  1. Minimum Requirements:

    • iOS 15.0 or above
  2. Update ios/Podfile:

    platform :ios, '15.0'
    
  3. 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

  1. Camera Permission Issues

    • Ensure proper permissions are declared in platform manifests
    • Request permissions before using face detection
  2. Build Errors on Android

    • Verify target SDK is 35 or above
    • Check that camera permissions are properly declared
  3. iOS Build Issues

    • Ensure iOS deployment target is 15.0 or above
    • Verify camera usage description is added to Info.plist
  4. 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.