Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Finally, a Camera Control for Xamarin!

1 Apr 2019 1  
Quickly leverage the cameras on mobile devices without needing to know the native camera APIs.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Introduction

The LEADTOOLS Camera Control is the latest in the LEADTOOLS SDK for Xamarin. It solves the glaring need in the Xamarin Forms community for a high-level control that developers can use to easily leverage mobile device cameras. Using the LEADTOOLS Camera Control requires no knowledge of the iOS and Android native camera APIs since LEADTOOLS takes care of all that for you. The LEADTOOLS Camera Control provides total control of the camera, including flash, focus, resolution and more.

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)
{
	ReadBarcode(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!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here