
# QuickCapture Mobile Document Scanning & Imaging 

[![Pub Version](https://img.shields.io/pub/v/quickcapture.svg)](https://pub.dev/packages/quickcapture)

**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 11 or later.

## Other Available Platform Options
- [Android](https://github.com/ExtrieveTechnologies/QuickCapture_Android)
- [iOS](https://github.com/ExtrieveTechnologies/QuickCapture_IOS)
- [React Native](https://www.npmjs.com/package/@extrieve_technologies/quickcapture_react_native)

## API Methods

### 1. `activateLicense`
Activates the license for the Quickcapture plugin.
```dart
Future<bool?> activateLicense(String,String);
```
#### Example
```dart
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.
```dart
Future<String?> initialize();
```
#### Example
```dart
@override
void initState() {
  super.initState();
  _quickCapturePlugin.initialize();
}
```
### 3. `startCapture`
Starts the document capture process and returns the details of the captured images.
```dart
_quickCapturePlugin.startCapture();
```
#### Example
```dart
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.
```dart
Future<String?> buildPDFForLastCapture();
```

#### Example
```dart
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.
```dart
_quickCapturePlugin.buildTIFFForLastCapture();
```

#### Example
```dart
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.
```dart
Future<String?> compressToJPEG(String imagePath);
```

#### Example
```dart
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.

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

#### Example
```dart
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.

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

#### Example
```dart
 // 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:
```json
//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.

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

#### Example
```dart
 // 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:
```json
//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.
```dart
Future<bool?> initHumanFaceHelper()
```
#### Example
```dart
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.
```dart
Future<String?> detectHumanFaces(String imagePath)
```
#### Example
```dart
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:
```json
{
  "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.
```dart
  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
```dart
String? matchResponse = await _quickcapturePlugin.matchHumanFaces(
  firstDocumentID,
  firstDocumentFaceIndex,
  secondDocumentID,
  secondDocumentFaceIndex,
);
print("Match result: $matchResponse");
```
##### Response:
```json
//On success
{
  "STATUS": true,
  "ACCURACY": 85,
  "DESCRIPTION": "<Standard explanation for match>"
}

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

### **Match Level Descriptions**

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%**        | **Perfect Match**        | Faces match perfectly! The similarity is extremely high, and they are almost certainly the same person. |
| **80% - 89%**         | **Strong Match**         | Faces matched successfully. The similarity is high, indicating a strong likelihood of being the same person. |
| **65% - 79%**         | **Moderate Match**       | Faces show a good match. Some features match well, but additional validation may be necessary.      |
| **50% - 64%**         | **Low Confidence Match** | Faces share some similarity, but the match is not strong enough to confirm. Results are inconclusive. |
| **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**

- **Perfect Match (90% - 100%)**: 
  - Suitable for high-confidence applications such as secure identity verification or critical decision-making scenarios.
  
- **Strong Match (80% - 89%)**: 
  - Applicable where a high probability of matching is sufficient, but users may choose to review the results for added assurance.

- **Moderate Match (65% - 79%)**: 
  - Recommended for use in general-purpose applications. Additional manual validation may be required to confirm the match.

- **Low Confidence Match (50% - 64%)**: 
  - Results are inconclusive. Users should consider re-evaluating with higher-quality images or alternative methods.

- **No Match (0% - 49%)**: 
  - Faces are highly unlikely to match. This can be used as a definitive rejection in most cases.

---

## 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
```dart
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
```dart
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](https://pub.dev/packages/collection)

### 2. **Flutter**
- **Source**: Flutter SDK
- **Purpose**: Core framework for building the plugin and integrating with Flutter applications.
- **Documentation**: [Flutter Framework](https://flutter.dev)

### 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](https://pub.dev/packages/plugin_platform_interface)

## Notes
- **Initialization**: Always call `initialize` before using the plugin.
- **License Activation**: Ensure the license is activated before use for all features.

For more information, refer to the [Quickcapture documentation](https://www.extrieve.com/products/quickcapture/mobile/).

[© 1996 - 2025 Extrieve Technologies](https://www.extrieve.com/)
