The DocumentCameraFrame
package simplifies document scanning by providing a customizable camera
interface for capturing and cropping document images. Itβs ideal for applications that require
efficient and user-friendly document capture.
- Document Frame: Customizable dimensions for focused document capture.
- Camera Preview: Real-time camera feed for instant feedback.
-
User-Friendly Controls:
- Capture: Take a snapshot of the document.
- Save: Save the captured image.
- Retake: Retake the image if unsatisfactory.
-
Customizable UI:
- Define frame dimensions, button styles, and positions.
- Add optional titles with alignment and padding options.
-
Event Callbacks: Handle events like
onCaptured
,onSaved
, andonRetake
easily.
Add the package to your Flutter project using:
flutter pub add document_camera_frame
Then run:
flutter pub get
Add the following keys to your ios/Runner/Info.plist
file to request camera and microphone
permissions:
<plist version="1.0">
<dict>
<!-- Add the following keys inside the <dict> section -->
<key>NSCameraUsageDescription</key>
<string>We need camera access to capture documents.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need microphone access for audio-related features.</string>
</dict>
</plist>
- Update the
minSdkVersion
to 21 or higher inandroid/app/build.gradle
:
android {
defaultConfig {
minSdk 21
}
}
- Add these permissions to your
AndroidManifest.xml
file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application android:label="MyApp" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<!-- Activities and other components -->
</application>
</manifest>
Permission errors may occur when initializing the camera. You must handle them appropriately. Below are the possible error codes:
Error Code | Description |
---|---|
CameraAccessDenied |
User denied camera access permission. |
CameraAccessDeniedWithoutPrompt |
iOS only. User previously denied access and needs to enable it manually via Settings. |
CameraAccessRestricted |
iOS only. Camera access is restricted (e.g., parental controls). |
AudioAccessDenied |
User denied microphone access permission. |
AudioAccessDeniedWithoutPrompt |
iOS only. User previously denied microphone access and needs to enable it manually via Settings. |
AudioAccessRestricted |
iOS only. Microphone access is restricted (e.g., parental controls). |
import 'package:document_camera_frame/document_camera_frame.dart';
import 'package:document_camera_frame/document_camera_frame.dart';
import 'package:flutter/material.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: DocumentCameraFrame(
frameWidth: 330.0,
frameHeight: 240.0,
// captureButtonTextStyle: const TextStyle(fontSize: 24),
// captureButtonStyle: ElevatedButton.styleFrom(
// backgroundColor: Colors.white,
// foregroundColor: Colors.black,
// padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 10),
// ),
// captureButtonWidth: 140,
// captureButtonHeight: 40,
screenTitle: const Text(
'Capture Your Document',
style: TextStyle(color: Colors.white, fontSize: 20),
),
captureButtonText: 'Snap',
saveButtonText: 'Keep',
retakeButtonText: 'Retry',
onCaptured: (imgPath) {
debugPrint('Captured image path: $imgPath');
},
onSaved: (imgPath) {
debugPrint('Saved image path: $imgPath');
},
onRetake: () {
debugPrint('Retake button pressed');
},
),
),
);
}
}
Parameter | Type | Description | Required | Default Value |
---|---|---|---|---|
frameWidth |
double |
Width of the document capture frame. | β | β |
frameHeight |
double |
Height of the document capture frame. | β | β |
screenTitle |
Widget? |
Title widget to display on the screen (optional). | β | null |
screenTitleAlignment |
Alignment? |
Alignment of the screen title (optional). | β | Alignment.topCenter |
screenTitlePadding |
EdgeInsets? |
Padding for the screen title (optional). | β | EdgeInsets.zero |
captureButtonText |
String? |
Text for the "Capture" button. | β | "Capture" |
captureButtonTextStyle |
TextStyle? |
Text style for the "Capture" button text (optional). | β | null |
captureButtonStyle |
ButtonStyle? |
Style for the "Capture" button (optional). | β | null |
captureButtonAlignment |
Alignment? |
Alignment of the "Capture" button (optional). | β | null |
captureButtonPadding |
EdgeInsets? |
Padding for the "Capture" button (optional). | β | null |
captureButtonWidth |
double? |
Width for the "Capture" button (optional). | β | null |
captureButtonHeight |
double? |
Height for the "Capture" button (optional). | β | null |
onCaptured |
Function(String) |
Callback when an image is captured. | β | β |
saveButtonText |
String? |
Text for the "Save" button. | β | "Save" |
saveButtonTextStyle |
TextStyle? |
Text style for the "Save" button text (optional). | β | null |
saveButtonStyle |
ButtonStyle? |
Style for the "Save" button (optional). | β | null |
saveButtonAlignment |
Alignment? |
Alignment of the "Save" button (optional). | β | null |
saveButtonPadding |
EdgeInsets? |
Padding for the "Save" button (optional). | β | null |
saveButtonWidth |
double? |
Width for the "Save" button (optional). | β | null |
saveButtonHeight |
double? |
Height for the "Save" button (optional). | β | null |
onSaved |
Function(String) |
Callback when an image is saved. | β | β |
retakeButtonText |
String? |
Text for the "Retake" button. | β | "Retake" |
retakeButtonTextStyle |
TextStyle? |
Text style for the "Retake" button text (optional). | β | null |
retakeButtonStyle |
ButtonStyle? |
Style for the "Retake" button (optional). | β | null |
retakeButtonAlignment |
Alignment? |
Alignment of the "Retake" button (optional). | β | null |
retakeButtonPadding |
EdgeInsets? |
Padding for the "Retake" button (optional). | β | null |
retakeButtonWidth |
double? |
Width for the "Retake" button (optional). | β | null |
retakeButtonHeight |
double? |
Height for the "Retake" button (optional). | β | null |
onRetake |
VoidCallback? |
Callback when the "Retake" button is pressed. | β | null |
imageBorder |
BoxBorder? |
Border for the captured image preview (optional). | β | null |
animationDuration |
Duration? |
Duration for any animations (optional). | β | null |
animationColor |
Color? |
Color for animation effects (optional). | β | null |
This project is licensed under the MIT License. See the LICENSE file for details.