Skip to content

Repository files navigation

Plugin.Maui.DocumentScanner

NuGet CI

Native document scanning for .NET MAUI — no paid SDK required.

dotnet add package Plugin.Maui.DocumentScanner
  • Android: ML Kit document scanner (full scanner UI, auto-crop, filters; models downloaded via Google Play services)
  • iOS: VisionKit document camera for scanning, plus Vision document segmentation with a built-in corner editor for cropping already-taken photos

Supports Android API 23+ (Google Play services 23.39+, device RAM 1.7 GB+) and iOS 15+.

Setup

Register the plugin in MauiProgram.cs:

builder
    .UseMauiApp<App>()
    .UseDocumentScanner();

UseDocumentScanner() registers IDocumentScanner in dependency injection and hooks the Android activity-result plumbing — no MainActivity changes needed.

iOS: camera permission

ScanAsync opens the camera, so add a usage description to Platforms/iOS/Info.plist — iOS terminates the app without it:

<key>NSCameraUsageDescription</key>
<string>Scan documents with the camera.</string>

ScanFromPhotosAsync uses the system photo picker and needs no photo-library permission.

Android

No permissions or manifest changes are required. ML Kit downloads its scanner module through Google Play services on first use, so the first scan on a device can take a few seconds longer.

Usage

Inject IDocumentScanner (or use DocumentScanner.Default without DI):

// Camera scan — returns file paths of cropped pages, empty list if the user cancels
IReadOnlyList<string> pages = await scanner.ScanAsync();

// iOS only: pick already-taken photos, then adjust each crop in the corner editor.
// On Android this throws NotSupportedException, so guard it.
if (OperatingSystem.IsIOS())
    pages = await scanner.ScanFromPhotosAsync();

// With options
pages = await scanner.ScanAsync(new DocumentScanOptions
{
    PageLimit = 3,
    Mode = DocumentScannerMode.Base, // Android only: Full, BaseWithFilter, or Base
});

// With cancellation — dismisses the native UI and throws OperationCanceledException
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2));
pages = await scanner.ScanAsync(cancellationToken: cts.Token);

Check scanner.IsSupported first — on Android it also verifies Google Play services is 23.39 or newer, which the scanner requires. If a device slips past it (too little RAM, under-spec hardware), ScanAsync throws NotSupportedException.

Returned files are JPEGs written to the app's cache directory — move or copy them if you need them to persist.

Platform notes

Android iOS
ScanAsync ML Kit scanner UI, with an import-from-gallery button VisionKit document camera
ScanFromPhotosAsync Not supported — ML Kit cannot start in the gallery, so the API throws NotSupportedException Photo picker + auto-detected corners + manual corner editor
PageLimit Applies to the scanner ScanFromPhotosAsync only (VisionKit has no limit)
Mode Full / BaseWithFilter / Base Ignored

Sample

The samples/ScanTest app exercises both scan paths and shows page sizes and timings. To deploy it to a physical iPhone, copy ScanTest.local.props.example to ScanTest.local.props and fill in your signing identity.

Changelog

See CHANGELOG.md.

About

Native document scanning for .NET MAUI — ML Kit on Android, VisionKit on iOS

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages