flutter_better_scanner library
A drop-in document scanner for Flutter.
Two ways to use it:
1. Built-in UI — one call:
final result = await BetterScanner.openScanner(
context,
config: const ScannerConfig(
captureMode: CaptureMode.multiple,
shutterMode: ShutterMode.auto,
autoCrop: true,
autoEnhance: true,
exportFormat: ExportFormat.jpg,
),
);
final paths = result?.imagePaths ?? [];
2. Your own UI — drive the controller:
final controller = ScannerController(config: myConfig);
await controller.initialize();
// In your build():
ScannerPreview(controller: controller)
// Wire up your own buttons:
controller.cycleFlashMode();
controller.switchCamera();
controller.setGuide(ScanGuide.a4);
controller.setShutterMode(ShutterMode.auto);
controller.setDetectionQuality(DetectionQuality.medium);
await controller.capture();
await controller.pickFromGallery();
final result = await controller.finish();
Live detection state (outline, hint, auto-capture progress) is published
through controller.detection, a ValueListenable that updates per frame
without rebuilding the camera preview.
3. Your own review screen. The same controller backs the page list,
so a custom preview needs no extra plumbing — it is a ListenableBuilder
over controller.pages:
// Read
controller.pages; // List<ScanPage>
controller.proxyPath(page); // thumbnail file to show
page.enhancement, page.rotationQuarterTurns, page.cropCorners;
// Edit — each call re-renders and notifies listeners
controller.rotatePage(page);
controller.flipPage(page);
controller.setPageEnhancement(page, ScanEnhancement.magicColor);
controller.setPageAdjustments(page, brightness: 12, contrast: 1.2);
controller.setPageCrop(page, corners);
controller.duplicatePage(page);
controller.deletePage(page);
controller.reorderPages(oldIndex, newIndex);
controller.rename('Invoice 42');
// Borrow a built-in editor from your own screen
await controller.openCropEditor(context, page);
await controller.openEnhanceEditor(context, page);
await controller.openAnnotateEditor(context, page);
// Build your own filter strip
final thumbs = await controller.renderEnhancementThumbnails(page);
final result = await controller.finish(); // exports, returns paths
4. A-la-carte — one editor, on any image. No camera, no session, no package UI around it. Give it a path, get a new path back:
final cropped = await ScannerEditor.crop(context, imagePath: path);
final enhanced = await ScannerEditor.enhance(context, imagePath: path);
final signed = await ScannerEditor.annotate(context, imagePath: path);
// Headless — no screen is shown at all:
final turned = await ScannerEditor.rotate(imagePath: path);
final tidy = await ScannerEditor.autoCrop(imagePath: path);
final bw = await ScannerEditor.applyEnhancement(
imagePath: path, enhancement: ScanEnhancement.blackWhite);
// Or hand the package a pile of images and let it run the whole
// review screen over them:
final result = await ScannerEditor.editImages(
context, imagePaths: myPaths);
Classes
- AutoCaptureTuning
- Timing and sensitivity of automatic capture.
- BetterScanner
- One-call entry points for the document scanner.
- DetectionState
- Immutable snapshot of the live detection, published on every frame.
- GridOverlay
- Rule-of-thirds grid.
- GuideOverlay
- Paper-size framing guide (A4 / Letter).
- PreviewScreen
- Multi-page review screen: reorder, per-page editors, add more pages, and a single confirm action that finishes the session.
- PreviewTools
- Which per-page editors the built-in preview screen offers.
- Quad
-
Quadrilateral as 4 corners, TL/TR/BR/BL. Coordinates are either
normalized
0,1(detection output) or pixels (warp input) — the owner tracks which. - QuadOverlay
- Paints the detected document outline and the auto-capture ring.
- ScannedPage
- One finished page of a scan session.
- ScannerConfig
- Everything the scanner needs to know, in one immutable object.
- ScannerController
- Headless scanner engine.
- ScannerEditor
- A-la-carte access to the package's editors, for apps that manage their own images and their own UI.
- ScannerPermissions
- Camera permission checks, requests and the settings deep link.
- ScannerPreview
- Live camera preview with the detection outline, framing guide and grid composited on top.
- ScannerScreen
- The package's camera screen. Pops a ScanResult.
- ScannerTheme
- Colours used by the built-in screens.
- ScanPage
- A page inside a live scan session.
- ScanResult
- What a scan session produced.
Enums
- AfterCapture
- What the scanner does after a page is captured.
- CameraFacing
- Which physical camera to open.
- CaptureMode
- How many pages a scanning session may produce.
- DetectionQuality
- How hard the live edge detector works per frame.
- ExportFormat
- File type produced when a session finishes.
- ScanEnhancement
- Image enhancement applied to a page.
- ScanGuide
- Framing guide drawn over the camera preview.
- ScanHint
- What the scanner is telling the user right now.
- ScannerFlashMode
- Torch / flash behaviour while scanning.
- ScannerPermission
- Camera permission state, normalized across Android and iOS.
- ScannerStatus
- Why the camera is not showing a preview.
- ScanStatus
- Why a scan session ended.
- ShutterMode
- Shutter behaviour.