Implementing Anyline

This section will guide you through the implementation process of an Anyline Scan View, including configuration and handling scan results.

Adding a Scan View

  • Open the MainPage.xaml file in your project tree
  • In the Source tab, change the XML Code to the example shown below
<Page
        x:Class="ExampleApp.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:ExampleApp"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:anyline="using:Anyline.SDK.Modules.Mrz"> <!--Add the anyline module namespace here-->

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
                <!--Add the anyline scan view here-->
                <anyline:MrzScanView x:Name="AnylineScanView" PreferredCameraDevice="ExternalFront" />
        </Grid>
</Page>

Now, you’ve integrated the MRZ scan module to your page, but there are a few more steps necessary to initialize, configure and receive scan results. If you want to implement a different module, you’ll find these under the Anyline.SDK.Modules namespace. The Barcode module is part of the Energy namespace.

Providing a View Configuration to the Scan View

With the Anyline View Configuration, you can define the Look & Feel of your scanning app.

The configuration parameters define the visual information presented to the user, as well as the scan settings (like the resolution, etc.).

The full parameter list of the configuration can be found at Anyline View Configuration.

You can adapt your scan view easily by adding the configuration as a .json file as an asset to your project.

  • In your Assets treenode, right-click on the folder and select Add > New Item..
  • Choose Visual C# > Text File and name it MrzConfig.json

Make sure that the build action for this file is set to Content.

Now open the file and paste the code from the following example:

{
        "captureResolution":"1080p",

        "cutout": {
                "style": "rect",
                "maxWidthPercent": "90%",
                "maxHeightPercent": "90%",
                "alignment": "center",
                "strokeWidth": 2,
                "cornerRadius": 4,
                "strokeColor": "FFFFFF",
                "outerColor": "000000",
                "outerAlpha": 0.3,
                "feedbackStrokeColor": "0099FF",
                "cropOffset": {
                        "x": 10,
                        "y": 20
                }
        },
        "flash": {
                "mode": "manual",
                "alignment": "bottom_right"
        },
        "beepOnResult": true,
        "vibrateOnResult": true,
        "blinkAnimationOnResult": true,
        "cancelOnResult": true,
        "visualFeedback": {
                "style": "RECT",
                "strokeColor": "0099FF",
                "fillColor": "220099FF",
                "animationDuration": 70
        }
}

The View Configuration can be set via

Set the View Configuration
AnylineScanView.SetConfigFromAsset("Assets/MrzConfig.json");

Note

Detailed information for each parameter can be found at Full Parameter List in the View Configuration section

Configuring and initializing the scan view in your code-behind

You can access the Scan View to your MainPage in one of the following ways:

// for barcode & energy meter scanning
using Anyline.SDK.Modules.Energy;

// for MRZ scanning
using Anyline.SDK.Modules.Mrz;

The easiest way to get scan results is to let the MainPage implement the IMrzResultListener interface. In order to handle camera callbacks, it should also implement the ICameraListener. The ICameraListener interface is located in the Anyline.SDK.Camera namespace, therefore we will also add using Anyline.SDK.Camera; to the using statements at the top of the code-behind.

Visual Studio will now complain that MainPage does not implement the interface members, so let’s add them by clicking on the light bulb and selecting implement interface.

The empty MainPage.xaml.cs code-behind will now look like this:

using System;
using Windows.UI.Xaml.Controls;

using Anyline.SDK.Modules.Mrz;
using Anyline.SDK.Camera;
using Anyline.SDK.Models;

namespace ExampleApp
{
        public sealed partial class MainPage : Page, IMrzResultListener, ICameraListener
        {
                public MainPage()
                {
                        this.InitializeComponent();
                }

                public void OnCameraClosed(bool success)
                {
                        throw new NotImplementedException();
                }

                public void OnCameraError(Exception e)
                {
                        throw new NotImplementedException();
                }

                public void OnCameraOpened(uint width, uint height)
                {
                        throw new NotImplementedException();
                }

                public void OnResult(MrzResult scanResult)
                {
                        throw new NotImplementedException();
                }
        }
}

Now it’s time to actually load the view configuration, initialize the scan view, handle camera callbacks and scan results.

ScanMrz()

The default constructor ScanMrz() is the place to set up and initialize the Anyline scan view with the desired configuration and license key.

readonly string LicenseKey = "eyJzY29wZSI6WyJBTEwiXSwicGxhdGZvcm0iOlsiaU9TIiwiQW5kcm9pZCIsIldpbmRvd3MiXSwidmFsaWQiOiIyMDE4LTAzLTAyIiwibWFqb3JWZXJzaW9uIjoiMyIsImlzQ29tbWVyY2lhbCI6ZmFsc2UsInRvbGVyYW5jZURheXMiOjYwLCJpb3NJZGVudGlmaWVyIjpbIkV4YW1wbGVBcHAiXSwiYW5kcm9pZElkZW50aWZpZXIiOlsiRXhhbXBsZUFwcCJdLCJ3aW5kb3dzSWRlbnRpZmllciI6WyJFeGFtcGxlQXBwIl19ClI1WTRMNFhuaW5SbkU5VmZZbXZSYnlXRkFMT0h4QTY1OXJrWURBN2UzbGp5S0RNdG1HTm54T2grZm0vTmFLQW1CcE9vV0tzS0J2M0hsVjVYWkZZOXd3MmVrYmNYM2VSSmdnMUpFb3c0RDRpcFBCM1IvbWVadGR5T053TjdTNy9QOFRKU1hOSURXb1YxVXdyS3REUm9FUk1MTzJ0N3FYeTFXQXhVYW9NTXFDa2duemxPTTJKQ2ZtaGRxYmZjYlMySzN2RG1Zc0VJcUcwWGNpdHFsOWhJdmsxYmFSRVl4UlRnTllzdGtqOHVFdUZDV05veGIrVGNXNXRMc1YrR05JNnZZd2NISUxrOEt3N3NNcFI2cVI3Nmpzc2tRWm9HZ2NiUVZJMHgyeUY5MFdxcEd5TFd0bmNYNkhEMUNvbStEL1Qzd21XQmw5TmdtOU9URWlTT0pyRWdaUT09";

public MainPage()
{
        this.InitializeComponent();

        AnylineScanView.CameraListener = this;

        AnylineScanView.SetConfigFromAsset("Assets/MrzConfig.json");
        AnylineScanView.InitAnyline(LicenseKey, this);
}

The camera will be opened automatically, but in general can be opened with OpenCameraInBackground() and closed with ReleaseCameraInBackground(). The next thing we want to do is to tell the scan view when to start and stop scanning for MRZ esults.

We want to start scanning as soon as the camera is opened, and stop scanning when the camera is closed. We’ll also make sure scanning is stopped, the camera is closed and the reference to AnylineScanView is set to null when we navigate away from the page because this will free all resources and avoid memory leaks.

With StartScanning() and StopScanning() we can start and stop the scanning process.

Avoid spamming scan and camera methods

Note: StartScanning() creates a background thread and StopScanning() will release this thread, but spamming these methods can lead to undefined behaviour and crashes. Make sure they will not be spammed via button clicks for example. The same rule goes for OpenCameraInBackground() and ReleaseCameraInBackground(): spamming them might lead to unwanted camera behaviour and can even obstruct the camera sensor until a device restart is required.

After implementing the functionality, the complete code-behind will look like this:

using System;
using Windows.UI.Xaml.Controls;

using Anyline.SDK.Modules.Mrz;
using Anyline.SDK.Camera;
using Anyline.SDK.Models;
using System.Diagnostics;
using Windows.UI.Xaml.Navigation;

namespace ExampleApp
{
        public sealed partial class MainPage : Page, IMrzResultListener, ICameraListener
        {

                // this license key was generated for the package name "ExampleApp"
                readonly string LicenseKey = "eyJzY29wZSI6WyJBTEwiXSwicGxhdGZvcm0iOlsiaU9TIiwiQW5kcm9pZCIsIldpbmRvd3MiXSwidmFsaWQiOiIyMDE4LTAzLTAyIiwibWFqb3JWZXJzaW9uIjoiMyIsImlzQ29tbWVyY2lhbCI6ZmFsc2UsInRvbGVyYW5jZURheXMiOjYwLCJpb3NJZGVudGlmaWVyIjpbIkV4YW1wbGVBcHAiXSwiYW5kcm9pZElkZW50aWZpZXIiOlsiRXhhbXBsZUFwcCJdLCJ3aW5kb3dzSWRlbnRpZmllciI6WyJFeGFtcGxlQXBwIl19ClI1WTRMNFhuaW5SbkU5VmZZbXZSYnlXRkFMT0h4QTY1OXJrWURBN2UzbGp5S0RNdG1HTm54T2grZm0vTmFLQW1CcE9vV0tzS0J2M0hsVjVYWkZZOXd3MmVrYmNYM2VSSmdnMUpFb3c0RDRpcFBCM1IvbWVadGR5T053TjdTNy9QOFRKU1hOSURXb1YxVXdyS3REUm9FUk1MTzJ0N3FYeTFXQXhVYW9NTXFDa2duemxPTTJKQ2ZtaGRxYmZjYlMySzN2RG1Zc0VJcUcwWGNpdHFsOWhJdmsxYmFSRVl4UlRnTllzdGtqOHVFdUZDV05veGIrVGNXNXRMc1YrR05JNnZZd2NISUxrOEt3N3NNcFI2cVI3Nmpzc2tRWm9HZ2NiUVZJMHgyeUY5MFdxcEd5TFd0bmNYNkhEMUNvbStEL1Qzd21XQmw5TmdtOU9URWlTT0pyRWdaUT09";

                public MainPage()
                {
                        this.InitializeComponent();

                        AnylineScanView.CameraListener = this;

                        AnylineScanView.SetConfigFromAsset("Assets/MrzConfig.json");
                        AnylineScanView.InitAnyline(LicenseKey, this);
                }

                public void OnCameraClosed(bool success)
                {
                        if (AnylineScanView != null)
                                AnylineScanView.CancelScanning();
                }

                public void OnCameraError(Exception e)
                {
                        Debug.WriteLine("Error: " + e.Message);
                }

                public void OnCameraOpened(uint width, uint height)
                {
                        if (AnylineScanView != null)
                                AnylineScanView.StartScanning();
                }

                public void OnResult(MrzResult scanResult)
                {
                        Debug.WriteLine("Result: " + scanResult.Result);
                }

                protected override void OnNavigatedFrom(NavigationEventArgs args)
                {
                        base.OnNavigatedFrom(args);

                        if (AnylineScanView != null)
                        {
                                AnylineScanView.CancelScanning();
                                AnylineScanView.ReleaseCameraInBackground();
                        }
                        AnylineScanView = null;
                }
        }
}

Handling Scan Results

The Results of the Modules are provided by a ResultListener. Each Module has its own ResultListener. In the code above you can see an example of the IMrzResultListener Interface. For MRZ scanning , this result wil consist of an Identification and the AnylineImage that was captured at the time the result happened.

Test your app on your x86 Windows 10 device

Before you test your example application, make sure that you set the necessary device capabilities and set the build architecture to x86. Double-check your Package Name, make sure your webcam or camera is working.

Enjoy scanning!