Skip to content

Mobile data scanning(barcodes, text, documents...) plugin

License

Notifications You must be signed in to change notification settings

lucacivale/Plugin.Scanner

Repository files navigation

πŸ“± Plugin.Scanner

EARLY ALPHA

  • Planned
    • Custom data scanner view with overlay etc.
    • TextScanner and DocumentScanner

πŸš€ Mobile cross platform data scanner

NuGet License Platform Support Framework Support

This plugin aims to enalbe simple, fast and customizable data scanning(barcodes, text, documents...) using native Android and iOS APIs ML Kit and Vision Kit.

  • Platform support iOS 16+ and Android 23+
  • One shared API cross platforms and frameworks
  • Scan barcodes with only two lines of code

iOS iOS iOS

Android Android Android

πŸš€ Get started

πŸ”§ Platform specific setup

To access the scanner functionality, the following platform-specific setup is required. The application will crash without this setup.

iOS

In the Info.plist file, add the following keys and values:

<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to scan data.</string>
Android

The CAMERA permission is required and must be configured in the Android project. In addition:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />

⬇️ Installation

Install the NuGet package:

MAUI
dotnet add package Plugin.Scanner.Maui
Uno
dotnet add package Plugin.Scanner.Uno
Avalonia
dotnet add package Plugin.Scanner.Avalonia

Please note: If you encounter this issue, you will need to enable long path support as described here.

βš™οΈ Setup

MAUI

Enable the plugin in your MauiProgram.cs:

namespace Plugin.Scanner.Maui.Hosting;

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder.UseScanner();
    return builder.Build();
}
Uno

Enable the plugin in your App.xaml.cs:

using Plugin.Scanner.Uno.Hosting;

protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
    IApplicationBuilder builder = this.CreateBuilder(args)
        .UseScanner();
    MainWindow = builder.Window;

    Host = await builder.NavigateAsync<Shell>();
}
Avalonia

Initialize the plugin in your android MainActivity.cs:

protected override void OnCreate(Bundle? savedInstanceState)
{
    base.OnCreate(savedInstanceState);
     
    Hosting.Scanner.Init(this);
}

πŸ”³ Barcode scanning

Implementation details
MAUI & Uno

Resolve the registered IBarcodeScanner service and scan a single barcode in all supported formats

using Plugin.Scanner.Core.Barcode;
using Plugin.Scanner.Core.Exceptions;

public class MainViewModel
{
    private readonly IBarcodeScanner _barcodeScanner;

    public MainViewModel(IBarcodeScanner barcodeScanner)
    {
        _barcodeScanner = barcodeScanner;
    }

    public async Task ScanBarcode()
    {
        try
        {
            var barcode = await _barcodeScanner.ScanAsync(new BarcodeScanOptions() { Formats = BarcodeFormat.All }).ConfigureAwait(false);
        }
        catch(BarcodeScanException exception)
        {
            Debug.WriteLine(exception);
        }
    }
}
Avalonia

Since dependency injection is not available out of the box a static implementation of the scanner must be used. If you use dependency injection register the IBarcodeScanner serivce with the IServiceCollection.AddBarcodeScanner() extension method. See Maui and Uno examples.

using Plugin.Scanner.Core.Barcode;
using Plugin.Scanner.Core.Exceptions;

public partial class MainViewModel
{
    public async Task ScanBarcode()
    {
        try
        {
            var barcode = await BarcodeScanner.Default.ScanAsync(new BarcodeScanOptions() { Formats = BarcodeFormat.All }).ConfigureAwait(false);
        }
        catch (BarcodeScanException exception)
        {
            Debug.WriteLine(exception);
        }
    }
}

🟒 Detect only specific format(s)?

Create options and set the target formats(s)
var options = new BarcodeScanOptions
{
    Formats = BarcodeFormat.QR | BarcodeFormat.Ean13
};

using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));
var barcode = await scanner.ScanAsync(options, cts.Token);
Console.WriteLine($"Scanned: {barcode.RawValue}");

🟒 There are multiple barcodes in the frame?

Single recognition(default)
  • _barcodeScanner.ScanAsync(new BarcodeScanOptions())

    • First detected barcode is highlighted
    • Tap on target barcode to highlight it, display confirmation button and complete the scan

    Android iOS

Multiple recognition
  • _barcodeScanner.ScanAsync(new BarcodeScanOptions({ RecognizeMultiple = true }))

    • All detected barcodes are highlighted
    • Tap on the target barcode to display the confirmation button and complete the scan

    Android iOS

🟒 You don't want to highlight detected barcodes?

Highlighting enabled(default)
  • _barcodeScanner.ScanAsync(new BarcodeScanOptions())

    • All detected barcodes are highlighted

    Android iOS

Highlighting disabled
  • _barcodeScanner.ScanAsync(new BarcodeScanOptions({ IsHighlightingEnabled = false }))

    • No detected barcode is highlighted

    Android iOS

🟒 Allow a two-finger pinch-to-zoom gesture?

Pinch to zoom enabled(default)
  • _barcodeScanner.ScanAsync(new BarcodeScanOptions())

    Android iOS

Pinch to zoom disabled
  • _barcodeScanner.ScanAsync(new BarcodeScanOptions({ IsPinchToZoomEnabled = false }))
    • No zoom allowed

🟒 Detect barcodes only in a specific area?

Specify region of interest
BarcodeScanOptions options = new()
{
    RegionOfInterest = new CenteredRegionOfInterest(250, 200),
};
var barcode = (await _barcodeScanner.ScanAsync(options);
  • Adds a vertical and horizontal-centered 250x200 detection area

  • You can create your own area by implementing IRegionOfInterest

  • A region of interest will also add a visual overlay

    Android iOS

🟒 You don't like the default overlay? Create your own!

Keep in mind that when using a Custom Overlay, you are responsible for the entire overlay (you cannot mix and match custom elements with the default overlay).

Custom overlay

Implement Plugin.Scanner.Core.IOverlay on each platform to create your own overlay. See overlay for an example implementation.

A cross-platform example can be found here.
This is just a showcase and not a production-ready implementation.

Create a new instance and pass it to the options

BarcodeScanOptions options = new()
{
    Overlay = myAwesomeOverlay,
};

Releases

No releases published

Packages

 
 
 

Contributors