Extract Barcode Data from an Image Taken Using the LEADTOOLS Xamarin Camera Control

LEADTOOLS latest release included the introduction of the Xamarin Camera Control. This control eliminates the need to write native iOS or Android camera code. Developers can now engineer the camera control into their Xamarin.Forms application with one line of code.

Below is a tutorial on how to extract data from barcodes from images that have been taken using the Xamarin Camera Control. This example is great for developers who have been using the native iOS/Android code to access the devices camera to recognize barcodes.

Take a look below and see for yourself how much simpler this control is to use than using native code. If you have other ideas or questions with the Xamarin Camera Control, or any parts of the LEADTOOLS SDK, be sure to let us know!




Download Project

Set up Your Project

The first step is to retrieve a free 30-day evaluation license by registering at https://www.leadtools.com/downloads/nuget.

Create a new Project

Once you have a LEADTOOLS license, open Visual Studio 2017 and create a new project. Within the Visual C# tab, select Cross-Platform > Mobile App (Xamarin Forms). On the next page, select Blank and check Android and iOS for the Platform and Shared Project under Code Sharing Strategy. This will give you a starting template for the Xamarin.Forms application.

To get started using Leadtools.Camera.Xamarin, you must add references to the appropriate NuGet packages. To modify NuGet packages for the entire solution, right-click the solution in Visual Studio and select Manage NuGet packages for Solution.

The NuGet packages you will need to install are:

  • Leadtools.Camera.Xamarin
  • Leadtools.Barcode

Set up Permissions to Access the Device’s Camera

One other important thing that needs to be done is to update the permissions settings to request access to the camera. To do this, open the AndroidManifest.xml located in the Properties folder of the XamarinCameraProject.Android project and add the following lines inside the manifest element, not inside the application element:

   <uses-permission android:name="android.permission.CAMERA" />
   <uses-feature android:name="android.hardware.camera" />
</manifest>

Now open MainActivity.cs and replace the OnCreate function with the following code:

protected override void OnCreate(Bundle savedInstanceState)
{
   TabLayoutResource = Resource.Layout.Tabbar;
   ToolbarResource = Resource.Layout.Toolbar;

   base.OnCreate(savedInstanceState);
   RequestCameraPermission();
   Xamarin.Forms.Forms.Init(this, savedInstanceState);
   LoadApplication(new App());
}

private void RequestCameraPermission()
{
   const int requestPermissionCode = 0;
   
   if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) != Permission.Denied &&
       ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) != Permission.Denied &&
       ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) !=
       Permission.Denied) return;

   ActivityCompat.RequestPermissions(this, new[]
   {
      Manifest.Permission.Camera, Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage
   }, requestPermissionCode);
}

For iOS, open the Info.plist file in an XML editor (Visual Studio’s default GUI does not seem to support this), and add the following lines inside the dict element:

    <key>NSCameraUsageDescription</key>
    <string>This app needs access to the camera to take photos.</string>
    <key>NSPhotoLibraryUsageDescription</key>    
    <string>This app needs access to photos.</string>
</dict>

Now open the AppDelegate.cs file in the iOS project and replace the FinishedLaunching function with this:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
   Leadtools.Camera.Xamarin.iOS.Assembly.Use();
   global::Xamarin.Forms.Forms.Init();
   LoadApplication(new App());

   return base.FinishedLaunching(app, options);
}

The Code

The LEADTOOLS Camera Control is a Xamarin.Forms control that displays a live camera preview. Setting this up can be done in two lines of code. Open MainPage.xaml and add the following reference to the Leadtools.Camera.Xamarin assembly.

xmlns:leadtools="clr-namespace:Leadtools.Camera.Xamarin;assembly=Leadtools.Camera.Xamarin"

Now replace the default auto-generated label within the StackLayout with the Xamarin CameraView, as well as a button that will be used to take the picture.

<StackLayout>
   <leadtools:CameraView x:Name="leadCamera" CameraOptions="Rear" HorizontalOptions="FillAndExpand" 
                           VerticalOptions="FillAndExpand"/>
   <Button HorizontalOptions="FillAndExpand" Text="Snap Picture" Clicked="SnapClicked" />
</StackLayout>

Next, open MainPage.xaml.cs and add the following lines before InitializeComponent() to set the LEADTOOLS license that you received before and to initialize the assemblies that the LEADTOOLS Camera control requires. You must set your license or else the application will throw an exception at runtime.

#if __IOS__ 
   Leadtools.Converters.Assembly.Use(); 
#endif 
   Leadtools.Core.Assembly.Use(); 
   Leadtools.Svg.Assembly.Use(); 
   Leadtools.Camera.Xamarin.Assembly.Use(); 
   Leadtools.Platform.RuntimePlatform = Device.RuntimePlatform; 
   Leadtools.RasterSupport.Initialize(this);

   const string licString = "[License]∖n" + "License = <doc><ver>2.0</ver>`PASTE YOUR LICENSE CONTENTS HERE`</doc>"; 
   const string developerKey = "PASTE YOUR DEVELOPER KEY HERE"; 
   var licBytes = System.Text.Encoding.UTF8.GetBytes(licString); 
   Leadtools.RasterSupport.SetLicense(licBytes, developerKey);
   InitializeComponent();
}

Now that the foundation of the app is set up, add code to read a barcode from an image taken using the Camera Control. Within the CameraView Class is an event called PictureReceived that is fired when an image is captured by calling ICamera.TakePicture(). The call to the TakePicture method will go in the button click event.

void SnapClicked(object sender, EventArgs args)
{
	leadCamera.Camera.TakePicture();
}

To create the event handler for PictureReceived, add the following line of code after InitializeComponent():

   leadCamera.CameraOptions.AutoRotateImage = true;
   leadCamera.PictureReceived += LeadCamera_PictureReceived;

Every time PictureReceived is fired, it will call LeadCamera_PictureReceived which passes FrameHandlerEventArgs. FrameHandlerEventArgs has three properties:

  • Data, the captured image data
  • Image, the RasterImage associated with the capture operation
  • RotationDegree, the rotation in degrees required to rotate the frame to a portrait orientation

In this project, we use the Image property to get our captured image and then read and extract barcode data from it. Let’s create another function that will take the image and read any barcodes found. The function for this event should now look like this:

private void LeadCamera_PictureReceived(FrameHandlerEventArgs e)
{
	ReadBarcodes(e.Image);
}

Next, add code to the new ReadBarcodes function, which takes a RasterImage. LEADTOOLS is the most comprehensive barcode toolkit on the market and can detect and decode more than 100 linear and 2-dimensional barcode types in bitonal and color images.

public void ReadBarcode(RasterImage image)
{
   try
   {
      var reader = new BarcodeEngine().Reader;
      var dataArray = reader.ReadBarcodes(image, LeadRect.Empty, 0, null);
      if (dataArray == null)
      {
         Device.BeginInvokeOnMainThread(() =>
         {
            DisplayAlert("Alert", "No barcodes were found", "OK");
         });
         return;
      }
      var sb = new StringBuilder();
      sb.AppendLine($"{dataArray.Length} barcode(s) found");
      sb.AppendLine();
      foreach (var data in dataArray)
      {
         sb.AppendLine($@"
Symbology: {data.Symbology} 
Location: {data.Bounds.ToString()} 
Data: {data.Value}");
      }

      Device.BeginInvokeOnMainThread(() =>
      {
         DisplayAlert("Found Barcode(s)", sb.ToString(), "OK");
      });
   }
   catch (Exception ex)
   {
      Device.BeginInvokeOnMainThread(() =>
      {
         DisplayAlert("Alert", ex.ToString(), "OK");
      });
   }
}

That is it! Now build and run the application on your device and read some barcodes!

Leadtools.Camera.Xamarin provides Xamarin developers with a powerful high-level API to access and control mobile camera hardware without needing to know all of the idiosyncrasies associated with each native API.

Need help getting this sample up and going? Contact our support team for free technical support via email or chat!

This entry was posted in Barcode, Document Imaging, News and tagged , , . Bookmark the permalink.

One Response to Extract Barcode Data from an Image Taken Using the LEADTOOLS Xamarin Camera Control

  1. Pingback: Dew Drop – April 2, 2019 (#2930) | Morning Dew

Leave a Reply

Your email address will not be published. Required fields are marked *