Document Scanning Quick Start

Available on: iOS Android Web React Native Flutter Cordova Capacitor .NET MAUI

Overview

The Genius Scan SDK provides a pre-built scanning interface called ScanFlow that enables you to add document scanning to your app with just a few lines of code. ScanFlow is highly configurable, allowing you to adapt it to your specific needs. This guide will help you get started quickly.

Demo

The simple demo projects from our demo repository demonstrate how to configure document scanning.

Prerequisites

Before implementing document scanning, you need to install and configure the SDK.

Basic Implementation

Once you’ve installed and configured the SDK, implement document scanning in just a few lines:

// Create configuration
let configuration = GSKScanFlowConfiguration()
configuration.multiPage = true
configuration.pdfPageSize = .a4

// Start the scan flow
do {
  let result = try await GSKScanFlow(configuration: configuration)
    .resultByStarting(fromViewController: self)

  if let pdfUrl = result.multiPageDocumentURL {
    print("PDF saved at: \(pdfUrl)")
  } else {
    print("No PDF was generated")
  }
} catch {
  print("Scanning failed: \(error.localizedDescription)")
}

If you cannot use the modern Async/Await API, the SDK also provides closure-based APIs.

// Create configuration
val configuration = ScanFlowConfiguration().apply {
    multiPage = true
    pdfPageSize = ScanFlowConfiguration.PdfPageSize.A4
}

// Start the scan flow
val scanLauncher = registerForActivityResult(ScanActivity.Contract()) { output ->
    when (output) {
        is FlowOutput.Success -> {
            val pdfFile = output.result.multiPageDocument
            Log.d("Scanner", "PDF saved at: ${pdfFile?.absolutePath}")
        }
        is FlowOutput.Error -> {
            Log.e("Scanner", "Scanning failed", output.error)
        }
    }
}

scanLauncher.launch(configuration)
import { scanWithConfiguration } from "@thegrizzlylabs/web-geniusscan-sdk";

// Configure and launch scanner
try {
  const result = await scanWithConfiguration({
    multiPage: true,
    multiPageFormat: "pdf",
    pdfPageSize: "a4",
    jpegQuality: 60
  });

  // Handle the result
  const { scans, multiPageDocument } = result;

  // Process individual scanned pages
  for (const scan of scans) {
    const imageBlob = scan.enhancedImage.data;
    console.log("Scanned page:", imageBlob);
  }

  // Process PDF if generated
  if (multiPageDocument) {
    const pdfBlob = new Blob([multiPageDocument.data],
      { type: multiPageDocument.type });
    console.log("PDF generated:", pdfBlob);
  }
} catch (error) {
  // Handle error or user cancellation
  console.error("Scanning failed:", error);
}
import RNGeniusScan from '@thegrizzlylabs/react-native-genius-scan';

// Configure scan flow
try {
  // Launch scanner
  const result = await RNGeniusScan.scanWithConfiguration({
    multiPage: true,
    multiPageFormat: 'pdf',
    pdfPageSize: 'a4',
    jpegQuality: 60
  });

  // Handle the result
  const { multiPageDocumentUrl, scans } = result;
  console.log("PDF saved at:", multiPageDocumentUrl);

  // Process individual pages
  for (const scan of scans) {
    console.log("Page:", scan.enhancedUrl);
  }
} catch (error) {
  // Handle cancellation or error
  console.error("Scanning failed:", error);
}
import 'package:flutter_genius_scan/flutter_genius_scan.dart';

// Configure scan flow
var configuration = {
  'multiPage': true,
  'multiPageFormat': 'pdf',
  'pdfPageSize': 'a4',
  'jpegQuality': 60,
};

try {
  // Launch scanner
  var result = await FlutterGeniusScan.scanWithConfiguration(configuration);

  // Handle the result
  String? pdfUrl = result['multiPageDocumentUrl'];
  List<dynamic> scans = result['scans'];

  print("PDF saved at: $pdfUrl");

  // Process individual pages
  for (var scan in scans) {
    print("Page: ${scan['enhancedUrl']}");
  }
} catch (error) {
  // Handle cancellation or error
  print("Scanning failed: $error");
}
// Configure scan flow
var configuration = {
  multiPage: true,
  multiPageFormat: 'PDF',
  pdfPageSize: 'A4',
  jpegQuality: 60
};

// Launch scanner
cordova.plugins.GeniusScan.scanWithConfiguration(configuration,
  // Success callback
  function(result) {
    var pdfUrl = result.multiPageDocumentUrl;
    var scans = result.scans;

    console.log("PDF saved at:", pdfUrl);

    // Process individual pages
    scans.forEach(function(scan) {
      console.log("Page:", scan.enhancedUrl);
    });
  },
  // Error callback
  function(error) {
    console.error("Scanning failed:", error);
  }
);
import GeniusScan from '@thegrizzlylabs/capacitor-plugin-genius-scan';

// Configure scan flow
try {
  // Launch scanner
  const result = await GeniusScan.scanWithConfiguration({
    source: 'camera',
    multiPage: true,
    multiPageFormat: 'pdf',
    pdfPageSize: 'a4',
    jpegQuality: 60
  });

  // Handle the result
  const { multiPageDocumentUrl, scans } = result;
  console.log("PDF saved at:", multiPageDocumentUrl);

  // Process individual pages
  for (const scan of scans) {
    console.log("Page:", scan.enhancedUrl);
  }
} catch (error) {
  // Handle cancellation or error
  console.error("Scanning failed:", error);
}

For .NET MAUI, use the ScanFlowService to start the document scan flow:

using GeniusScanSDK.ScanFlow;
var scanFlowService = new ScanFlowService();
var configuration = new Dictionary<string, object>
{
    ["source"] = "camera",
    ["ocrConfiguration"] = new Dictionary<string, object>
    {
        ["languages"] = new[] { "en-US" }
    }
};
var result = await scanFlowService.ScanDocument(configuration);
var documentUrl = (string)result["multiPageDocumentUrl"];

The examples above use a minimal scan flow configuration to start scanning and return a document. From there, you can enable additional features such as OCR, barcode extraction, source selection, UI customization, and output controls. The options below show what can be configured on each platform.

Configuration Options

ScanFlow configuration controls how the scan flow is presented, what output it generates, and which optional processing is requested. The table below lists actual configuration options and shows where each one is available.

Configuration option iOS Android Cross-platform Web
Scan source
Choose camera, photo library, or provided image input.
-
Source image
Provide the image to scan when the source is an existing image.
-
Multi-page mode
Let users capture several pages in one scan flow.
Multi-page output format
Choose the document generated from captured pages.
PDF page size
Set the page size used for generated PDFs.
PDF max scan dimension
Downscale scans before PDF generation.
-
PDF text-layer font
Use a custom font for searchable PDF text.
-
PDF title
Set the metadata title for generated PDFs.
- - -
JPEG quality
Control compression quality for captured images.
Original image output
Include the original unprocessed image in the scan result.
- - -
Skip post-processing screen
Return results without showing the review and edit screen.
-
Post-processing actions
Choose which edit actions users can access.
Default filter
Select the enhancement applied by default.
Available filters
Restrict the filters users can choose from.
Default curvature correction
Apply curvature correction by default.
-
Default scan orientation
Rotate scans automatically or keep the original orientation.
-
Photo library button visibility
Hide or show the photo import button.
-
Flash button visibility
Hide or show the camera flash control.
-
Default flash mode
Choose flash behavior when capture starts.
-
Required readability level
Warn users when scans may be blurry or unreadable.
-
OCR
Run text recognition and choose OCR output formats.
-
Structured data extraction
Extract receipts, barcodes, or other structured data.
-
Barcode types for structured data
Limit which barcode symbologies are searched in documents.
-
Background color
Customize the scan flow background color.
Foreground color
Customize text and icon colors.
Highlight color
Customize detection overlays and accent color.
Menu color
Customize menu styling where supported.
- -
Localization language
Control or inherit the scan flow UI language.
* * *

* Adapts to the platform language. 20 languages are available; see Localization.

Cross-platform covers React Native, Flutter, Cordova, Capacitor, and .NET MAUI. Some options are platform-specific in effect: for example, menu color maps to the iOS ScanFlow menu color, while Android does not expose a native menu color option. The detailed option names and accepted values differ by platform, so use the references below when implementing your configuration.

For allowed values, defaults, and platform-specific behavior, refer to the API and package references:

Localization

The SDK is localized in 20 of the most commonly used languages.

The features of the SDK will be localized in the device’s active language, except for the Web SDK for which you can specify the language in the configuration with the "language": "fr" key/value.

What’s Next?

At this point, you already have a working document scanner. If the default ScanFlow experience covers your use case, you can stop here. When you need more control or additional capabilities, explore these guides:

Ready to get started?

Start with a free trial license to test the SDK, or contact us directly for a custom quote tailored to your needs.

Products

Industries

Case Studies

Integration

Company

© 2026 The Grizzly Labs. All rights reserved.