document_camera_frame 2.0.4

SDKflutter
Platformandroidios

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

Document Camera Frame

Pub Version Pub Points Likes

DocumentCameraFrame is a Flutter package for scanning documents using a live camera feed. It provides a customizable frame UI, dual-side capture support (e.g., front/back of ID cards), automatic document detection, and easy integration for OCR or document processing workflows.

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
  • 🔄 Dual-Side Capture Support (e.g., ID front/back)
  • 🎛️ Fully Customizable UI — titles, padding, button styles
  • 🪝 Easy Event CallbacksonCaptured, onRetake, onSaved

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
      onBothSidesSaved: (documentData) {
        print('Document saved: ${documentData.frontImagePath}');
        Navigator.pop(context);
      },
    );
  }
}

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 CodeDescription
CameraAccessDeniedUser denied camera access permission.
CameraAccessDeniedWithoutPromptiOS only. User previously denied access and needs to enable it manually via Settings.
CameraAccessRestrictediOS only. Camera access is restricted (e.g., parental controls).
AudioAccessDeniedUser denied microphone access permission.
AudioAccessDeniedWithoutPromptiOS only. User previously denied microphone access and needs to enable it manually via Settings.
AudioAccessRestrictediOS 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'),
  onBothSidesSaved: (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",
  onBothSidesSaved: (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,
  onBothSidesSaved: (data) => processIdCard(data),
)

Widget Parameters

Core Parameters

ParameterTypeDescriptionRequiredDefault Value
frameWidthdoubleWidth of the document capture frame.
frameHeightdoubleHeight of the document capture frame.
enableAutoCaptureboolEnables automatic capture when a document is properly aligned in the frame.false
requireBothSidesboolWhether to require both sides (if false, can save with just front side).true
showCloseButtonboolFlag to control the visibility of the CloseButton (optional).false
cameraIndexint?Index to specify which camera to use (e.g., 0 for back, 1 for front) (optional).0 (back)
bottomFrameContainerChildWidget?Custom content for the bottom container (optional).null
bottomHintTextString?Optional bottom hint text shown in the bottom container.null
sideInfoOverlayWidget?Optional widget shown on the right (e.g. a check icon).null

Styling Classes

ParameterTypeDescriptionRequiredDefault Value
animationStyleDocumentCameraAnimationStyleAnimation styling configuration for the camera widget.DocumentCameraAnimationStyle()
frameStyleDocumentCameraFrameStyleFrame styling configuration for borders and appearance.DocumentCameraFrameStyle()
buttonStyleDocumentCameraButtonStyleButton styling configuration for all buttons.DocumentCameraButtonStyle()
titleStyleDocumentCameraTitleStyleTitle styling configuration for screen titles.DocumentCameraTitleStyle()
sideIndicatorStyleDocumentCameraSideIndicatorStyleSide indicator styling configuration.DocumentCameraSideIndicatorStyle()
progressStyleDocumentCameraProgressStyleProgress indicator styling configuration.DocumentCameraProgressStyle()
instructionStyleDocumentCameraInstructionStyleInstruction text styling configuration.DocumentCameraInstructionStyle()

Callbacks

ParameterTypeDescriptionRequiredDefault Value
onFrontCapturedFunction(String)?Callback triggered when front side is captured.null
onBackCapturedFunction(String)?Callback triggered when back side is captured.null
onBothSidesSavedFunction(DocumentCaptureData)Callback triggered when both sides are captured and saved.
onRetakeVoidCallback?Callback triggered when the "Retake" button is pressed.null
onCameraErrorvoid Function(Object error)?Callback triggered when a camera-related error occurs (e.g., initialization, streaming, or capture failure).null

Styling Classes Details

DocumentCameraAnimationStyle

PropertyTypeDescriptionDefault Value
capturingAnimationDurationDuration?Duration for the capturing animation (optional).null
capturingAnimationColorColor?Color for the capturing animation (optional).null
capturingAnimationCurveCurve?Curve for the capturing animation (optional).null
frameFlipDurationDurationDuration for the flip animation between sides.Duration(milliseconds: 1200)
frameFlipCurveCurveCurve for the flip animation between sides.Curves.easeInOut

DocumentCameraFrameStyle

PropertyTypeDescriptionDefault Value
outerFrameBorderRadiusdoubleRadius of the outer border of the frame.12.0
innerCornerBroderRadiusdoubleRadius of the inner corners of the frame.8.0
frameBorderBoxBorder?Border for the displayed frame (optional).null

DocumentCameraButtonStyle

PropertyTypeDescriptionDefault Value
captureOuterCircleRadiusdouble?Radius of the outer circle of the capture button.null
captureInnerCircleRadiusdouble?Radius of the inner circle of the capture button.null
captureButtonTextString?Text for the "Capture" button.null
captureFrontButtonTextString?Text for capture button when capturing front side.null
captureBackButtonTextString?Text for capture button when capturing back side.null
saveButtonTextString?Text for the "Save" button.null
nextButtonTextString?Text for "Next" button (when moving from front to back).null
previousButtonTextString?Text for "Previous" button (when going back to front).null
retakeButtonTextString?Text for the "Retake" button.null
captureButtonStyleButtonStyle?Style for the "Capture" button (optional).null
actionButtonStyleButtonStyle?Style for action buttons (optional).null
retakeButtonStyleButtonStyle?Style for the "Retake" button (optional).null
captureButtonAlignmentAlignment?Alignment of the "Capture" button (optional).null
captureButtonPaddingEdgeInsets?Padding for the "Capture" button (optional).null
captureButtonWidthdouble?Width for the "Capture" button (optional).null
captureButtonHeightdouble?Height for the "Capture" button (optional).null
actionButtonAlignmentAlignment?Alignment of action buttons (optional).null
actionButtonPaddingEdgeInsets?Padding for action buttons (optional).null
actionButtonWidthdouble?Width for action buttons (optional).null
actionButtonHeightdouble?Height for action buttons (optional).null
captureButtonTextStyleTextStyle?Text style for the "Capture" button text (optional).null
actionButtonTextStyleTextStyle?Text style for action buttons (optional).null
retakeButtonTextStyleTextStyle?Text style for the "Retake" button text (optional).null

DocumentCameraTitleStyle

PropertyTypeDescriptionDefault Value
titleWidget?Widget to display as the screen's title (optional).null
frontSideTitleWidget?Custom title for front side capture.null
backSideTitleWidget?Custom title for back side capture.null
screenTitleAlignmentAlignment?Alignment of the screen title (optional).null
screenTitlePaddingEdgeInsets?Padding for the screen title (optional).null

DocumentCameraSideIndicatorStyle

PropertyTypeDescriptionDefault Value
showSideIndicatorboolShow the side indicator (optional).true
sideIndicatorBackgroundColorColor?Background color for side indicator.null
sideIndicatorBorderColorColor?Border color for side indicator.null
sideIndicatorActiveColorColor?Active color for side indicator.null
sideIndicatorInactiveColorColor?Inactive color for side indicator.null
sideIndicatorCompletedColorColor?Completed color for side indicator.null
sideIndicatorTextStyleTextStyle?Text style for side indicator text.null

DocumentCameraProgressStyle

PropertyTypeDescriptionDefault Value
progressIndicatorColorColor?Color for the progress indicator (optional).null
progressIndicatorHeightdoubleHeight of the progress indicator.4.0

DocumentCameraInstructionStyle

PropertyTypeDescriptionDefault Value
frontSideInstructionString?Instruction text for front side capture.null
backSideInstructionString?Instruction text for back side capture.null
instructionTextStyleTextStyle?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.