blink_shot 1.0.0+1
blink_shot: ^1.0.0+1 copied to clipboard
A Flutter package for blink detection and Blink Shot photo flow.
blink_shot #
A Flutter package for blink-triggered photo capture using camera and Google ML Kit face detection.
blink_shot provides a camera preview widget with blink detection and auto-capture capabilities. Use BlinkShotController for lifecycle control and event handling.
Features #
- Blink detection based on left/right eye-open probability history
- Ready-to-use camera preview widget with face alignment feedback
- Automatic capture when a blink is detected
- Manual capture mode when auto-capture is disabled
- Low-level APIs for custom camera or detection pipelines
Platform support #
- Android
- iOS
Desktop and web are not primary targets for this package because the blink flow depends on the mobile camera stack and ML Kit face detection.
Installation #
flutter pub add blink_shot
Platform setup #
blink_shot uses the device camera and face detection. The host app must provide the required platform permissions.
Android #
Add camera permission to your app manifest:
<uses-permission android:name="android.permission.CAMERA" />
Path: android/app/src/main/AndroidManifest.xml
iOS #
Add a camera usage description to your app Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is required to capture photos.</string>
Path: ios/Runner/Info.plist
This project is currently configured around iOS 13.0 in the example app and iOS project files.
Quick start #
Use BlinkShotController with BlinkShotView for automatic capture, state management, and event handling:
import 'package:blink_shot/blink_shot.dart';
import 'package:flutter/material.dart';
class BlinkCapturePage extends StatefulWidget {
const BlinkCapturePage({super.key});
@override
State<BlinkCapturePage> createState() => _BlinkCapturePageState();
}
class _BlinkCapturePageState extends State<BlinkCapturePage> {
late final BlinkShotController _controller;
String _status = 'Initializing camera...';
@override
void initState() {
super.initState();
_controller = BlinkShotController(
config: const BlinkShotConfig(
autoCapture: true,
showDefaultOverlay: true,
showDefaultStatusText: true,
),
onCapture: (file) {
debugPrint('Captured file: ${file.path}');
},
onError: (error) {
if (!mounted) return;
setState(() {
_status = 'Error: $error';
});
},
onStateChanged: (state) {
if (!mounted) return;
setState(() {
_status = switch (state) {
BlinkShotState.initializing => 'Initializing camera...',
BlinkShotState.ready => 'Blink to capture',
BlinkShotState.capturing => 'Capturing...',
BlinkShotState.paused => 'Paused',
BlinkShotState.error => 'Camera error',
BlinkShotState.disposed => 'Disposed',
};
});
},
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Blink Shot')),
body: Column(
children: [
Expanded(
child: BlinkShotView(
controller: _controller,
instructionText: 'Align your face and blink once',
),
),
Padding(
padding: const EdgeInsets.all(16),
child: Text(_status),
),
],
),
);
}
}
Configuration #
BlinkShotConfig controls capture and UI behavior:
| Property | Default | Description |
|---|---|---|
openThreshold |
0.7 |
Average eye-open score required to treat both eyes as open |
closedThreshold |
0.25 |
Average eye-open score required to treat both eyes as closed |
historyLength |
8 |
Number of frames used when evaluating a blink |
autoCapture |
true |
Automatically take a picture when a blink is detected |
cameraLensDirection |
CameraLensDirection.front |
Preferred camera |
showDefaultOverlay |
true |
Shows the built-in face alignment frame |
showDefaultStatusText |
true |
Shows the built-in status label |
Example:
final controller = BlinkShotController(
config: const BlinkShotConfig(
autoCapture: false,
openThreshold: 0.8,
closedThreshold: 0.2,
historyLength: 10,
showDefaultOverlay: false,
),
);
When autoCapture is false, BlinkShotView shows a capture button instead of taking a photo automatically.
Direct detector usage #
If you already have your own face or eye-tracking pipeline, you can use BlinkDetector directly:
final detector = BlinkDetector(
historyLength: 8,
openThreshold: 0.6,
closedThreshold: 0.25,
);
void onFrame(double? leftEyeOpenProbability, double? rightEyeOpenProbability) {
detector.add(leftEyeOpenProbability, rightEyeOpenProbability);
if (detector.didBlink) {
capturePhoto();
detector.reset();
}
}
Lower-level APIs #
BlinkDetectortracks blink state from eye-open probabilitiesFaceBlinkProcessorcombines ML Kit face detection with blink detectionBlinkShotControllermanages camera initialization, preview, frame processing, capture, pause, and resumeBlinkShotViewrenders the preview and optional default UI
Controller state #
BlinkShotController can report these states through onStateChanged:
initializingreadycapturingpausederrordisposed
Useful controller methods:
initialize()capture()pause()resume()resetBlinkDetector()
Notes #
- The built-in blink flow is intended for front-camera selfie capture.
BlinkDetectorandBlinkShotConfigdo not share the same defaultopenThreshold. The controller usesBlinkShotConfig, whose default is0.7.- In controller mode, handle captured files through
BlinkShotController.onCapture.
Example app #
See example/lib/main.dart for a complete integration example.
License #
MIT License. See LICENSE.