QuickCapture Mobile Document Scanning & Imaging

Pub Version

Extrieve Technologies - Your Expert in Document Management & AI Solutions

The Quickcapture Flutter plugin enables document scanning & imaging using mobile devices. It can integrates seamlessly with mobile applications, providing high-quality document capture, compression, optimization, and conversion into PDF and TIFF formats.

Key Features

  • High-Quality Capture: Optimized focus control for document scanning.
  • Compression & Optimization: Generate small, high-quality outputs for fast uploads.
  • DPI and Layout Control: Adjust DPI, layouts, and output sizes for PDF/TIFF.
  • Multi-Format Output: Supports output in both PDF and TIFF format output build.
  • Developer-Friendly: Easy integration into your Flutter applications.

Note: It's not "just" a scanning SDK. It's a document scanning SDK built with Best Quality, Highest Possible Compression, and Image Optimization on in mind that works fully offline & on device.

Compatibility

  • Java: Requires Java 17 or later.
  • Android:
    • Minimum SDK: API 21
    • Target SDK: API 35
    • Compiled SDK: API 34
  • iOS:
    • Requires iOS 13 or later.
    • Only real devices are supported; simulator support is not provided due to the size limitations of the Flutter plugin.
    • Additionally, Apple's simulator does not support camera functionalities, making it unsuitable for testing document capture features.

Other Available Platform Options

API Methods

1. activateLicense

Activates the license for the Quickcapture plugin.

Future<bool?> activateLicense(String,String);

Example

Future<bool?> activateLicense({
  required String android,
  required String ios,
});

// Parameters
// - `android`: License string for Android.
// - `ios`: License string for iOS.

// Return Value
// - `true` if the license was successfully activated.
// - `false` or `null` otherwise.

2. initialize

Initializes the Quickcapture plugin. This is required before calling other methods.

Future<String?> initialize();

Example

@override
void initState() {
  super.initState();
  _quickCapturePlugin.initialize();
}

3. startCapture

Starts the document capture process and returns the details of the captured images.

_quickCapturePlugin.startCapture();

Example

Future<void> startCapture() async {
  String? response = await _quickCapturePlugin.startCapture();
  
  if (response != null) {
    Map<String, dynamic> jsonResponse = jsonDecode(response);
    List<String> capturedImages = List<String>.from(jsonResponse['fileCollection']);
    print("Captured Images: $capturedImages");
  } else {
    print("Capture failed or cancelled.");
  }
}

4. buildPDFForLastCapture

Generates a PDF file from the images captured in the last session.

Future<String?> buildPDFForLastCapture();

Example

Future<void> buildPDF() async {
  String? pdfFilePath = await _quickCapturePlugin.buildPDFForLastCapture(); 
  if (pdfFilePath != null) {
    print("PDF generated at: $pdfFilePath");
  } else {
    print("Failed to generate PDF.");
  }
}

5. buildTIFFForLastCapture

Generates a TIFF file from the images captured in the last session.

_quickCapturePlugin.buildTIFFForLastCapture();

Example

Future<void> buildTIFF() async {
  String? tiffPath = await _quickCapturePlugin.buildTIFFForLastCapture();
  if (tiffPath != null) {
    print("TIFF generated at: $tiffPath");
  } else {
    print("Failed to generate TIFF.");
  }
}

6. compressToJPEG

Generates an optimized and compressed output image path in JPEG format.

Future<String?> compressToJPEG(String imagePath);

Example

Future<void> compressImage() async {
  String imagePath = "path/to/image.jpg";
  String? compressedImagePath = await _quickCapturePlugin.compressToJPEG(imagePath);
  if (compressedImagePath != null) {
    print("Compressed image at: $compressedImagePath");
  } else {
    print("Failed to compress image.");
  }
}

7. setCustomLayout

Customizes layout dimensions, such as setting specific dimensions like 200x300 pixels, which can impact the quality of the output image.

Future<bool?> setCustomLayout(int customWidth, int customHeight);

Example

bool? isCustomLayoutSet = await _quickCapturePlugin.setCustomLayout(500, 900); // in pixels
if (isCustomLayoutSet == true) {
  print("Custom layout set successfully.");
}

8. buildPDF

Create a compressed & optimised single PDF output file by merging provided collection of input images.

Future<String?> buildPDF(List<String> imagePaths);

Example

 // Extract paths of selected images
final List<String> imagePaths = "<image path list>";

// Pass the image paths to the buildPDF function
final String? jsonResponse = await _quickcapturePlugin.buildPDF(imagePaths);
Response:
//On Success:
{
  "status": true,
  "description": "PDF created successfully",
  "filePath": "/path/to/generated.pdf"
}

// On Failure :
{
  "status": false,
  "description": "No images provided",
  "filePath": null
}

9. buildTiff

Create a compressed & optimised single TIFF output file by merging provided collection of input images.

Future<String?> buildTiff(List<String> imagePaths);

Example

 // Extract paths of selected images
final List<String> imagePaths = "<image path list>";

// Pass the image paths to the buildPDF function
final String? jsonResponse = await _quickcapturePlugin.buildTiff(imagePaths);
Response:
//On Success:
{
  "status": true,
  "description": "TIFF created successfully",
  "filePath": "/path/to/generated.tiff"
}

// On Failure :
{
  "status": false,
  "description": "No images provided",
  "filePath": null
}

HumanFaceHelper

The QuickCapture plugin provides an advanced option to detect and match human faces in images. Below is an overview of these methods with detailed explanations.

API Methods

1. initHumanFaceHelper

Initializes the Human Face Helper module required for face detection and matching. An active license should needed for this.

Future<bool?> initHumanFaceHelper()

Example

bool? initialized = await _quickcapturePlugin.initHumanFaceHelper();
if (initialized == true) {
  print("Human Face Helper initialized successfully.");
} else {
  print("Failed to initialize Human Face Helper.");
}

// Returns : 
// true: Initialization successful.
// false: Initialization failed.

2. detectHumanFaces

Detects human faces in the specified image and provides bounding box coordinates for each detected face.

Future<String?> detectHumanFaces(String imagePath)

Example

String? response = await _quickcapturePlugin.detectHumanFaces(imagePath);
if (response != null) {
  Map<String, dynamic> result = jsonDecode(response);
  if (result["STATUS"] == true) {
    print("Faces detected: ${result["DATA"]}");
  } else {
    print("Face detection failed: ${result["DESCRIPTION"]}");
  }
}
Response:
{
  "STATUS": true,
  "DESCRIPTION": "SUCCESS",
  "CODE": 0,
  "IDENTIFIER": 12456, //Unique Document ID of the image.
  "DATA": [
    {
      "INDEX": 1, //The Face index of the first detected face in the current document : 12456
      "LEFT": 2517,
      "RIGHT": 3963,
      "TOP": 1187,
      "BOTTOM": 2538
    },
     {
      "INDEX": 2,//The Face index of the second detected face in the current document : 12456
      "LEFT": 277,
      "RIGHT": 2963,
      "TOP": 187,
      "BOTTOM": 538
    }
  ]
}

3. matchHumanFaces

Compares two detected faces and determines their similarity.

  Future<String?> matchHumanFaces(
      {required int firstDocumentID,
      required int firstDocumentFaceIndex,
      required int secondDocumentID,
      required int secondDocumentFaceIndex})

//firstDocumentID: Document ID of the first image.
//firstDocumentFaceIndex: Face index of the first face.
//secondDocumentID: Document ID of the second image.
//secondDocumentFaceIndex: Face index of the second face.

Example

String? matchResponse = await _quickcapturePlugin.matchHumanFaces(
  firstDocumentID,
  firstDocumentFaceIndex,
  secondDocumentID,
  secondDocumentFaceIndex,
);
print("Match result: $matchResponse");
Response:
//On success
{
  "STATUS": true,
  "ACCURACY": 85,
  "DESCRIPTION": "<Standard explanation for match>"
}

// On failure
{
  "STATUS": false,
  "ACCURACY": null,
  "DESCRIPTION": "<Technical reason for failure>"
}

Face Match Accuracy Interpretation

The match level is determined based on the accuracy percentage, which reflects the similarity between two facial images. The table below provides detailed descriptions for each match level.

Match Percentage Match Level Description
90% - 100% Highly Reliable Match Faces match with extremely high confidence. They are almost certainly the same person. Suitable for critical identification applications.
75% - 89% Strong Match Faces matched successfully with a high probability of being the same person. Reliable for most identity verification use cases.
65% - 74% ⚠️ Moderate Match Faces show good similarity, but further validation may be required. Manual verification is recommended before confirmation.
50% - 64% ⚠️ Low Confidence Match Faces have some resemblance, but the similarity is not strong enough to confirm identity. Additional verification is needed.
0% - 49% No Match Faces do not match. There is minimal similarity, and they are highly unlikely to be the same person.

Usage of Results

Highly Reliable Match (90% - 100%)

  • Best for: Secure identity verification, biometric authentication, and critical decision-making.
  • Action: Automatic acceptance. No further review required.

Strong Match (75% - 89%)

  • Best for: General identification scenarios where strong confidence is required.
  • Action: Safe for automatic approval in most applications.

⚠️ Moderate Match (65% - 74%)

  • Best for: Cases where additional review is acceptable before finalizing the decision.
  • Action: Manual verification recommended before confirming a match.

⚠️ Low Confidence Match (50% - 64%)

  • Best for: Situations requiring strict validation before acceptance.
  • Action: Use alternative verification methods. Do not rely on this score alone.

No Match (0% - 49%)

  • Best for: Definitive rejection of mismatches.
  • Action: Automatically reject matches in this range.

Configurations

The Config class provides detailed control over the image and capture settings.

1. Image Configuration

Use ConfigImage to manage image-specific settings.

Property Description
ImageQuality Quality of the output image (e.g., photoQuality, documentQuality, compressedDocument).
DPI DPI of the output (e.g., 150, 200, 300).
LayoutType Document layout (e.g., A3, A4, A5).
ResizeMode Strategy for resizing the image:
- preserveAspectOnly (default, recommended): Maintains aspect ratio while scaling.
- stretchToExactSize: Forces exact width and height, may distort.
- fitWithAspect: Fits within dimensions, maintaining aspect ratio with padding.

Recommended Settings:

  • ImageQuality: documentQuality
  • DPI: 150 or 200
  • LayoutType: A4
  • ResizeMode: preserveAspectOnly

Example

Quickcapture _quickcapturePlugin = Quickcapture();
Config imgConfig = _quickcapturePlugin.config.image;
imgConfig.setImageQuality(ImageQuality.documentQuality);
imgConfig.setDPI(DPI.dpi200);
imgConfig.setLayoutType(LayoutType.A4);
imgConfig.setResizeMode(ResizeMode.preserveAspectOnly);

2. Capture Configuration

Use ConfigCapture to manage capture-specific settings.

Property Description
captureSound Enables or disables capture sound (true/false).
enableFlash Enables or disables flash during capture (true/false).
showCaptureCountAndLimit Displays capture count and limit (true/false).
colorMode Sets the color mode (rgb, grayScale).
maxPage Limits the number of pages to capture. (0 = unlimited).
cameraToggle Switch between front/back cameras (enableBackDefault, enableFrontDefault).
bottomStampData BottomStampData - This configuration will automatically print the specified text at the bottom of the captured image with correct alignment, font size and DPI. This also supports placeholders, such as {DATETIME}, which will be replaced with the current date and time from the device at the time of stamping. $ - for new line print.This will only support for captured with SDK camera image.

Example

Quickcapture _quickcapturePlugin = Quickcapture();
Config captureConfig = _quickcapturePlugin.config.capture;
captureConfig.enableFlash = true;
captureConfig.captureSound = false;
captureConfig.maxPage = 2;
captureConfig.cameraToggle = CameraToggleType.enableBackDefault;
captureConfig.bottomStampData = "Scanned on {DATETIME} $ Scanned User ID :123456";

Method Summary

Method Description Return Value
activateLicense Activates the plugin license. true on success.
initialize Initializes the plugin. void.
startCapture Starts document capture. JSON with capture details.
buildPDFForLastCapture Generates a PDF from the last capture. File path of the generated PDF.
buildTIFFForLastCapture Generates a TIFF from the last capture. File path of the generated TIFF.
setCustomLayout Sets custom layout dimensions. true on success.
compressToJPEG Compresses and optimizes an image. File path of the JPEG image.
initHumanFaceHelper Initializes the Human Face Helper module. void.
detectHumanFaces Detects human faces from the input image. JSON reponse of detection
matchHumanFaces Compares two detected faces and determines their similarity. JSON reponse of match
buildPDF Build compressed single PDF output file from a list of provided images. JSON reponse of the build
buildTiff Build compressed single TIFF output file from a list of provided images. JSON reponse of the build

Plugin Dependencies

To ensure smooth functionality and cross-platform compatibility, the plugin relies on the following dependencies.

1. Collection

  • Version: ^1.19.0
  • Purpose: Provides advanced collection manipulation utilities in Dart, such as:
    • Equality comparison
    • Ordering utilities
    • Additional helper methods
  • Documentation: Collection Package

2. Flutter

  • Source: Flutter SDK
  • Purpose: Core framework for building the plugin and integrating with Flutter applications.
  • Documentation: Flutter Framework

3. Plugin Platform Interface

  • Version: ^2.0.2
  • Purpose: Defines platform interface libraries for Flutter plugins, ensuring proper implementation for:
    • Android
    • iOS
    • Other supported platforms
  • Documentation: Plugin Platform Interface

Notes

  • Initialization: Always call initialize before using the plugin.
  • License Activation: Ensure the license is activated before use for all features.Replace placeholders like "<Your Android License Key>" and "<Your iOS License Key>" with your actual license keys provided by Extrieve Technologies.*

Regarding accuracy :

The accuracy of face detection and matching technologies depends on input image quality, including factors such as image distortion, rotation angles, lighting conditions, and color consistency. While offline solutions effectively reduce manual effort and operational costs, they do not guarantee 100% reliability in all scenarios. This system enables on-device verification, efficiently identifying doubtful matches and flagging them for backend verification within the offline environment. By integrating backend validation, the system enhances reliability without relying on external APIs. Additionally, when a match achieves high accuracy as defined in the accuracy thresholds, the system can be considered reliable even without backend verification, making it a valuable solution for offline scenarios where external validation is limited. For use cases demanding exceptionally high accuracy and reliability, an API-based advanced system is recommended.

Additional Information

Getting Help

For help getting started with Flutter, view the online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

Important

  • Privacy and Security: Always handle user data securely and ensure compliance with applicable laws and regulations when processing personal identification documents.
  • Error Handling: Implement proper error handling in your application to provide a smooth user experience.

© 1996 - 2025 Extrieve Technologies