DEV Community

Xiao Ling
Xiao Ling

Posted on • Updated on • Originally published at dynamsoft.com

How to Build Camera Barcode Scanner App in Xamarin.Forms

Xamarin is a cross-platform framework for building Android and iOS apps using .NET programming. The code structure of Xamarin Android and Xamarin iOS is different. For developers who want to construct UI for Android and iOS from a single codebase, Xamarin.Forms is the only solution. This article shares how to implement camera barcode scanner apps for both Android and iOS platforms using Xamarin.Forms. Since camera logic is platform-dependent, a bunch of platform-specific code is required.

camera barcode scanner in Xamarin.Forms

Getting Started with Xamarin.Forms

Setting Up Environment on Windows 10

  1. Run Visual Studio Installer and select Mobile development with .NET

    visual studio installer

  2. In Visual Studio 2019, click Tools > Options > Xamarin > iOS Settings > Pair to Mac. Add a Mac IP for remotely building and debugging iOS project.

    xamarin mac pair

  3. Click the Android icon to install Android SDKs and tools:

    xamarin android installation

The Hello World Program

We create a new project with the mobile app template:

Xamarin.Forms mobile app

To simplify the project, we select Blank.

Xamarin.Forms template

Build and test the project for iOS:

Xamarin.Forms iOS app

If there is nothing wrong, we can take a further step to add code for camera preview.

Peeking Xamarin Camera-relevant APIs

To avoid re-inventing the wheel, we'd better search for Xamarin camera APIs beforehand. Unfortunately, there is only Media Picker available in Xamarin.Essentials. The MediaPicker class lets a user pick or take a photo or video on the device. But what we want is a custom camera view that allows us to do barcode scanning by processing video frames.

Although there is no Xamarin Camera API existed, Xamarin Github repository contains two useful sample code demonstrating how to implement custom content page and view:

It is not as convenient as React Native and Flutter camera plugin, though, it is better than nothing.

The two samples implement camera logic differently. The content page sample uses the deprecated Android Camera APIs, whereas the view sample uses the Android Camera2 APIs. The compatibility of Android Camera2 APIs is so far not good for many devices. If you are not going to dig too many camera functionalities, Android Camera APIs are still the best choice.

Implementing Barcode Scanning using Xamarin.Forms

Now, let's implement our own barcode scanner app.

First, we install Dynamsoft Xamarin Barcode Reader SDK respectively for Android and iOS projects via NuGet.

Xamarin Barcode SDK

Xamarin Shared Code Project

In the shared code project, we define some camera control interfaces in Interfaces/ICaptureUI.cs:

public interface ICaptureUI: IDisposable
{
    /// <summary>
    /// Starts the Capture Session.
    /// </summary>
    void StartSession();

    /// <summary>
    /// Stops the Capture Session.
    /// </summary>
    void StopSession();

    /// <summary>
    /// Determines if the Capture Session is active.
    /// </summary>
    bool GetSessionActive();

    /// <summary>
    /// res.
    /// </summary>
    string GetResults();

    /// <summary>
    /// Turn on or off the flash.
    /// </summary>
    void onClickFlash();
}
Enter fullscreen mode Exit fullscreen mode

We create Controls/CaptureUI.cs which extends ContentView and is bound to platform-specific camera view:

public class CaptureUI : ContentView
{

}
Enter fullscreen mode Exit fullscreen mode

A capture view model ViewModels/CaptureViewModel.cs is implemented for receiving the barcode scanning results:

class CaptureViewModel : ViewModelBase
{
    public CaptureViewModel() 
    {

    }
    /// <summary>
    /// Begins a Capture Sequence, preparing the UI and the Timer.
    /// </summary>
    public void StartCaptureSequence()
    {
        CaptureHandler = App.CurrentCaptureUI;
        Timer t = new Timer(500);
        t.Elapsed += new ElapsedEventHandler(Timer_Tick);
        t.AutoReset = true;
        t.Enabled = true;
    }
    public void Timer_Tick(object source, ElapsedEventArgs e)
    {
        Instruction = CaptureHandler.GetResults();
    }

    /// <summary>
    /// The current Instruction to the User.
    /// </summary>
    public string Instruction
    {
        get { return _Instruction; }
        set
        {
            _Instruction = value;
            UpdateProperty();
        }
    }
    /// <summary>
    /// Backing Field for <see cref="Instruction"/>.
    /// </summary>
    private string _Instruction;

    private ICaptureUI CaptureHandler { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Finally, we open MainPage.xaml file to design the UI, adding the custom view and binding the barcode scanning results to a label:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:DBRXFSample.Controls"
             x:Class="DBRXFSample.MainPage">

    <Grid
        HorizontalOptions="FillAndExpand"
        VerticalOptions="FillAndExpand">
        <controls:CaptureUI x:Name="Capture"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand" />
        <Image Source="scannerbox" HorizontalOptions="Center" VerticalOptions="Center"/>
        <Label Text="DBR Is Scanning Continuously" TextColor="#FF4646" FontSize="18" HorizontalOptions="Center" Margin="0,100,0,0" />
        <StackLayout
            HorizontalOptions="Center"
            VerticalOptions="Center"
            Margin="0,480,0,0">
                <Button x:Name="flash" ImageSource="flashon" HorizontalOptions="Center" WidthRequest="50" HeightRequest="50" Clicked="flash_Clicked" />
                <Label x:Name="label" Text="{Binding Instruction}" TextColor="#000000" BackgroundColor="#7F999999"/>
        </StackLayout>
    </Grid>
</ContentPage>
Enter fullscreen mode Exit fullscreen mode

Xamarin barcode scanner design

Xamarin Android and iOS Project

The diagram shows the relationship between Xamarin.Forms view and platform-specific view.

According to Microsoft's online tutorial, we can quickly implement the corresponding camera views.

Afterward, we can use the following code to decode barcodes from video frames:

// Android
private static BarcodeReader barcodeReader = new BarcodeReader("LICENSE-KEY");

try
{
    YuvImage image = (YuvImage)msg.Obj;
    if (image != null)
    {
        int[] stridelist = image.GetStrides();
        TextResult[] text = barcodeReader.DecodeBuffer(image.GetYuvData(), previewWidth, previewHeight, stridelist[0], EnumImagePixelFormat.IpfNv21, "");
        if (text != null && text.Length > 0)
        {
            for (int i = 0; i < text.Length; i++)
            {
                if (i == 0)
                    msg1.Obj = "Code[1]: " + text[0].BarcodeText;
                else
                    msg1.Obj = msg1.Obj + "\n\n" + "Code[" + (i + 1) + "]: " + text[i].BarcodeText;
            }
        }
    }
}
catch (BarcodeReaderException e)
{
    msg1.Obj = "";
    e.PrintStackTrace();
}
Enter fullscreen mode Exit fullscreen mode
// iOS
DynamsoftBarcodeReader reader = new DynamsoftBarcodeReader("LICENSE-KEY");

results = reader.DecodeBuffer(buffer, width, height, bpr, EnumImagePixelFormat.Argb8888, "", out errorr);
if (results != null && results.Length > 0)
{
    for (int i = 0; i < results.Length; i++)
    {
        if (i == 0)
            result = "Code[1]: " + results[0].BarcodeText;
        else
            result = result + "\n\n" + "Code[" + (i + 1) + "]: " + results[i].BarcodeText;
    }
}
Enter fullscreen mode Exit fullscreen mode

Get the 30-day FREE Trial license.

Source Code

https://github.com/Dynamsoft/xamarin/tree/master/examples/XamarinForms

Top comments (0)