document_camera_frame 2.2.1 copy "document_camera_frame: ^2.2.1" to clipboard
document_camera_frame: ^2.2.1 copied to clipboard

Flutter package for capturing and cropping document images with a customizable camera interface.

Document Camera Frame #

Pub Version Pub Points Likes

DocumentCameraFrame is an enterprise-grade document scanner for Flutter. It bridges the gap between raw camera streams and structured data by combining real-time ML edge detection, perspective-corrected cropping, and secure on-device OCR.

πŸ’Ž Premium Scanning Capabilities #

⚑ Smart Capture Engine #

  • Intelligent Shutter: Real-time analysis of image stability and document alignment triggers auto-capture.
  • Dual-Sided Workflow: Native support for multi-step scanning (e.g., ID Front β†’ ID Back) with animated transitions.
  • Haptic Guidance: Integrated vibration patterns to guide users without them needing to look at the screen.

🎯 Precision Computer Vision #

  • ML Kit Edge Detection: Sub-millisecond boundary detection for precise document isolation.
  • Perspective Correction: Automatically transforms skewed or angled captures into flat, top-down professional documents.
  • Frame-to-Sensor Mapping: Ensures high-resolution sensor output matches the UI overlay perfectly, preventing "cutoff" edges.

🧠 On-Device Intelligence & OCR #

  • Privacy-First OCR: Extract text from Latin-script documents 100% offline. No API keys, no latency, no data leaks.
  • Context-Aware Hints: Dynamic UI prompts (e.g., "Move Closer", "Too Dark", "Centering...") to maximize first-time capture success.
  • Multi-Object Filtering: Smart logic to ignore background clutter and focus solely on the primary document.

🎨 Fully Decoupled UI #

  • Logic-Agnostic Design: The detection engine is separated from the UI, allowing you to build completely custom overlays while keeping the "brains."
  • Theming Engine: Full control over frame colors, stroke thickness, button styles, and hint typography.

πŸ” Security & Compliance #

  • Offline-Only: Designed for FinTech and HealthTechβ€”zero external network calls.
  • No Data Retention: Images stay in the app's sandbox; you control the lifecycle.

Demo #

Here's a quick preview of DocumentCameraFrame in action:

Auto Detection Example
Auto document edge detection in real-time
example1
Driver license dual-side capture (320Γ—200) with auto-capture and side indicators
example2
Passport scanning (300Γ—450) with manual capture button, no side indicators, and custom instructions
example3
ID card dual-side capture (320Γ—200) with auto-capture, hidden side indicators, and smooth transitions

Features #

  • πŸ“Έ Live Camera Preview with adjustable document frame
  • βœ‚οΈ Custom Frame Dimensions for precise cropping
  • πŸ”Ž Automatic Document Detection
  • πŸ“’ Live Guidance Engine β€” Real-time alignment feedback (e.g., "Move closer", "Move right")
  • πŸ”„ Dual-Side Capture Support (e.g., ID front/back)
  • πŸ“ Optional on-device OCR β€” set enableExtractText: true to get extracted text in the save callback (no API key, no internet). OCR is Latin-only (no Arabic).
  • πŸŽ›οΈ Fully Customizable UI β€” titles, padding, button styles
  • πŸͺ Easy Event Callbacks β€” onDocumentSaved, onFrontCaptured, onBackCaptured, onRetake

Quick Start #

Installation #

Add the package to your Flutter project using:

flutter pub add document_camera_frame

Minimal Example #

import 'package:document_camera_frame/document_camera_frame.dart';
import 'package:flutter/material.dart';

class QuickExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DocumentCameraFrame(
      frameWidth: 320,
      frameHeight: 200,
      requireBothSides: false,
      enableAutoCapture: true, // Enable automatic capture
      onDocumentSaved: (documentData) {
        print('Document saved: ${documentData.frontImagePath}');
        Navigator.pop(context);
      },
    );
  }
}

OCR (Text extraction) #

Note: OCR is Latin-only (no Arabic). The on-device ML Kit model supports English and other Latin-script languages only.

Set enableExtractText: true to run on-device text recognition after capture. The onDocumentSaved callback then receives DocumentCaptureData with:

  • frontImagePath / backImagePath β€” image file paths (unchanged)
  • frontOcrText / backOcrText β€” extracted text (when enableExtractText is true)

No API key or internet is required. OCR uses Google ML Kit and supports Latin script (English and other Latin-based languages). Arabic is not supported by the on-device model.

DocumentCameraFrame(
  frameWidth: 320,
  frameHeight: 200,
  enableExtractText: true,
  onDocumentSaved: (data) {
    print('Front text: ${data.frontOcrText}');
    print('Back text: ${data.backOcrText}');
  },
)

For custom OCR (e.g. from file paths elsewhere), use the exported OcrService class and its extractText(String imagePath) method.

Setup Requirements #

iOS Setup #

  1. Set the minimum iOS deployment target to 15.5 or higher in your ios/Podfile:
platform :ios, '15.5'  # or newer version
  1. 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>

Android Setup #

  1. Update the minSdkVersion to 21 or higher in android/app/build.gradle:
android {
    defaultConfig {
        minSdk 21
    }
}
  1. 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>

Handling Camera Access Permissions #

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).

Common Use Cases #

Driver's License (Both Sides) #

DocumentCameraFrame(
  frameWidth: 320,
  frameHeight: 200,
  frontSideTitle: Text('Scan Front of License', 
    style: TextStyle(color: Colors.white)),
  backSideTitle: Text('Scan Back of License',
    style: TextStyle(color: Colors.white)),
  requireBothSides: true,
  enableAutoCapture: true, // Automatically capture when document is aligned
  onFrontCaptured: (imagePath) => print('Front: $imagePath'),
  onBackCaptured: (imagePath) => print('Back: $imagePath'),
  onDocumentSaved: (data) => handleDocument(data),
)

Passport (Single Side) #

DocumentCameraFrame(
  frameWidth: 300,
  frameHeight: 450,
  title: Text('Scan Passport', style: TextStyle(color: Colors.white)),
  requireBothSides: false,
  showSideIndicator: false,
  enableAutoCapture: false, // Manual capture only
  frontSideInstruction: "Position passport within the frame",
  onDocumentSaved: (data) => handlePassport(data),
)

ID Card with Custom Styling #

DocumentCameraFrame(
  frameWidth: 320,
  frameHeight: 200,
  requireBothSides: true,
  enableAutoCapture: true,
  captureButtonText: "Take Photo",
  saveButtonText: "Done",
  retakeButtonText: "Try Again",
  progressIndicatorColor: Colors.blue,
  outerFrameBorderRadius: 16.0,
  onDocumentSaved: (data) => processIdCard(data),
)

Widget Parameters #

Core Parameters #

Parameter Type Description Required Default Value
frameWidth double Width of the document capture frame. βœ… β€”
frameHeight double Height of the document capture frame. βœ… β€”
enableAutoCapture bool Enables automatic capture when a document is properly aligned in the frame. ❌ false
requireBothSides bool Whether to require both sides (if false, can save with just front side). ❌ true
showCloseButton bool Flag to control the visibility of the CloseButton (optional). ❌ false
cameraIndex int? Index to specify which camera to use (e.g., 0 for back, 1 for front) (optional). ❌ 0 (back)
bottomFrameContainerChild Widget? Custom content for the bottom container (optional). ❌ null
bottomHintText String? Optional bottom hint text shown in the bottom container. ❌ null
sideInfoOverlay Widget? Optional widget shown on the right (e.g. a check icon). ❌ null
showDetectionStatusText bool Show the (dynamic) live detection status text (e.g. "Move closer"). ❌ true

Styling Classes #

Parameter Type Description Required Default Value
animationStyle DocumentCameraAnimationStyle Animation styling configuration for the camera widget. ❌ DocumentCameraAnimationStyle()
frameStyle DocumentCameraFrameStyle Frame styling configuration for borders and appearance. ❌ DocumentCameraFrameStyle()
buttonStyle DocumentCameraButtonStyle Button styling configuration for all buttons. ❌ DocumentCameraButtonStyle()
titleStyle DocumentCameraTitleStyle Title styling configuration for screen titles. ❌ DocumentCameraTitleStyle()
sideIndicatorStyle DocumentCameraSideIndicatorStyle Side indicator styling configuration. ❌ DocumentCameraSideIndicatorStyle()
progressStyle DocumentCameraProgressStyle Progress indicator styling configuration. ❌ DocumentCameraProgressStyle()
instructionStyle DocumentCameraInstructionStyle Instruction text styling configuration. ❌ DocumentCameraInstructionStyle()

Callbacks #

Parameter Type Description Required Default Value
onFrontCaptured Function(String)? Callback triggered when front side is captured. ❌ null
onBackCaptured Function(String)? Callback triggered when back side is captured. ❌ null
onDocumentSaved Function(DocumentCaptureData)? Callback when document is saved (one-sided e.g. passport, or both sides). One of onDocumentSaved or onBothSidesSaved required. βœ…* β€”
onBothSidesSaved Function(DocumentCaptureData)? Deprecated. Use onDocumentSaved instead. Still supported for backward compatibility. βœ…* β€”
enableExtractText bool When true, runs on-device OCR and sets documentData.frontOcrText / backOcrText before the callback. ❌ false
onRetake VoidCallback? Callback triggered when the "Retake" button is pressed. ❌ null
onCameraError void Function(Object error)? Callback triggered when a camera-related error occurs (e.g., initialization, streaming, or capture failure). ❌ null

*At least one of onDocumentSaved or onBothSidesSaved must be provided. Prefer onDocumentSaved.

Styling Classes Details #

DocumentCameraAnimationStyle #

Property Type Description Default Value
capturingAnimationDuration Duration? Duration for the capturing animation (optional). null
capturingAnimationColor Color? Color for the capturing animation (optional). null
capturingAnimationCurve Curve? Curve for the capturing animation (optional). null
frameFlipDuration Duration Duration for the flip animation between sides. Duration(milliseconds: 1200)
frameFlipCurve Curve Curve for the flip animation between sides. Curves.easeInOut

DocumentCameraFrameStyle #

Property Type Description Default Value
outerFrameBorderRadius double Radius of the outer border of the frame. 12.0
innerCornerBroderRadius double Radius of the inner corners of the frame. 8.0
frameBorder BoxBorder? Border for the displayed frame (optional). null

DocumentCameraButtonStyle #

Property Type Description Default Value
captureOuterCircleRadius double? Radius of the outer circle of the capture button. null
captureInnerCircleRadius double? Radius of the inner circle of the capture button. null
captureButtonText String? Text for the "Capture" button. null
captureFrontButtonText String? Text for capture button when capturing front side. null
captureBackButtonText String? Text for capture button when capturing back side. null
saveButtonText String? Text for the "Save" button. null
nextButtonText String? Text for "Next" button (when moving from front to back). null
previousButtonText String? Text for "Previous" button (when going back to front). null
retakeButtonText String? Text for the "Retake" button. null
captureButtonStyle ButtonStyle? Style for the "Capture" button (optional). null
actionButtonStyle ButtonStyle? Style for action buttons (optional). null
retakeButtonStyle ButtonStyle? Style for the "Retake" 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
actionButtonAlignment Alignment? Alignment of action buttons (optional). null
actionButtonPadding EdgeInsets? Padding for action buttons (optional). null
actionButtonWidth double? Width for action buttons (optional). null
actionButtonHeight double? Height for action buttons (optional). null
captureButtonTextStyle TextStyle? Text style for the "Capture" button text (optional). null
actionButtonTextStyle TextStyle? Text style for action buttons (optional). null
retakeButtonTextStyle TextStyle? Text style for the "Retake" button text (optional). null

DocumentCameraTitleStyle #

Property Type Description Default Value
title Widget? Widget to display as the screen's title (optional). null
frontSideTitle Widget? Custom title for front side capture. null
backSideTitle Widget? Custom title for back side capture. null
screenTitleAlignment Alignment? Alignment of the screen title (optional). null
screenTitlePadding EdgeInsets? Padding for the screen title (optional). null

DocumentCameraSideIndicatorStyle #

Property Type Description Default Value
showSideIndicator bool Show the side indicator (optional). true
topPosition double? Side indicator position from the top (optional). null
rightPosition double? Side indicator position from the right (optional). null
sideIndicatorBackgroundColor Color? Background color for side indicator. null
sideIndicatorBorderColor Color? Border color for side indicator. null
sideIndicatorActiveColor Color? Active color for side indicator. null
sideIndicatorInactiveColor Color? Inactive color for side indicator. null
sideIndicatorCompletedColor Color? Completed color for side indicator. null
sideIndicatorTextStyle TextStyle? Text style for side indicator text. null

DocumentCameraProgressStyle #

Property Type Description Default Value
progressIndicatorColor Color? Color for the progress indicator (optional). null
progressIndicatorHeight double Height of the progress indicator. 4.0

DocumentCameraInstructionStyle #

Property Type Description Default Value
showInstructionText bool Show the (static) top instruction text. true
frontSideInstruction String? Instruction text for front side capture. null
backSideInstruction String? Instruction text for back side capture. null
instructionTextStyle TextStyle? Text style for instruction text (optional). null

πŸ”§ Troubleshooting #

Common Issues #

Camera not initializing:

  • βœ… Check camera permissions in device settings
  • βœ… Ensure minSdkVersion is at least 21 (Android)
  • βœ… Verify camera permissions in Info.plist (iOS)

Build errors:

  • πŸ’‘ Run flutter clean && flutter pub get
  • πŸ’‘ Confirm all platform-specific setup is complete
  • πŸ’‘ Ensure minimum iOS deployment target is 15.5 or higher in your ios/Podfile

Permission denied errors:

  • ⚠️ Handle permission errors gracefully in your app UI
  • ⚠️ Guide users to enable permissions in device settings

βš™οΈ Performance Tips #

  • πŸ“± The package automatically manages camera resources
  • πŸ—‚οΈ Images are saved to the temporary directory by default
  • 🚫 Consider implementing proper error handling for production apps

πŸ“Œ Full Example #

For a comprehensive example with multiple document types, see
example/main.dart.

Contributing #

Contributions are welcome! If you find a bug or have a feature request, please open an issue or submit a pull request.

πŸ™Œ Support #

License #

This project is licensed under the MIT License. See the LICENSE file for details.