Welcome Guest! To enable all features, please Login or Register.

Notification

Icon
Error

Options
View
Last Go to last post Unread Go to first unread post
#1 Posted : Friday, July 12, 2019 10:25:28 AM(UTC)
Joe Kerrigan

Groups: Registered, Tech Support
Posts: 6


Using the CameraView offered by Leadtools.Camera.Xamarin, developers can easily integrate camera support into their apps on both Android and iOS. Packaged alongside CameraView is the AutoCapture class, which offers a suite of helper functions that can automatically detect when it is suitable to take an image from the device’s camera. Developers may find this functionality useful to supplement manual controls: for instance, a user may choose to take a picture by pressing a button, but AutoCapture can also perform this functionality automatically. Alternatively, AutoCapture can be used entirely on its own to easily capture images without requiring explicit user direction.

The snippets that follow outline one way AutoCapture’s functionality can be incorporated into a cross-platform Xamarin app. The snippets work by delineating between three “phases” of capture. In the first phase, no document of interest is detected in the frame. Once a document with text is detected, we move to a second phase where the user is prompted to hold their device still as the camera focuses. If the user fails to maintain a stable image during this phase, we return to the first phase to ensure a high-quality final capture. If the image remains stable for long enough and the camera focuses successfully, we move to the final phase: image capture. An image is captured from the device’s camera; the developer can then proceed to use the image however they please. After capturing, we return to the first phase to capture more images.

MainPage.xaml.cs:
Code:

using Leadtools;
using Leadtools.Camera.Xamarin;
using System.Diagnostics;
using System.Timers;
using Xamarin.Forms;

namespace AutoCaptureExample
{
   public partial class MainPage : ContentPage
   {
      private AutoCapture autoCapture;
      private bool holding = false; // flag indicating whether we're in the "hold still" phase
      private bool shouldCheckStability = false; // flag indicating whether we should check the hold stability, potentially invalidating the "hold still" phase
      private bool isCapturing = false; // flag indicating whether we are currently taking a picture
      private bool cameraFocused = false; // flag indicating whether the camera has been focused
      private Timer checkHoldStabilityTimer;
      private Stopwatch captureStopwatch;

      public MainPage()
      {
         string licString = ""; // TODO: your license goes here
         string key = ""; // TODO: your developer key goes here
         byte[] licBytes = System.Text.Encoding.UTF8.GetBytes(licString);
         RasterSupport.SetLicense(licBytes, key);

         InitializeComponent();

         // initialize autocapture
         autoCapture = new AutoCapture();
         // use text detection mode
         autoCapture.CaptureMethod = AutoCapture.AutoCaptureMethod.TextDetection;

         // set up a timer so we can check "hold stability" every 300ms
         checkHoldStabilityTimer = new System.Timers.Timer();
         checkHoldStabilityTimer.Interval = 300;
         checkHoldStabilityTimer.Elapsed += (s, _e) => { shouldCheckStability = true; }; // just resets the flag saying we should check it
         checkHoldStabilityTimer.AutoReset = true; // repeats the timer
         checkHoldStabilityTimer.Enabled = true; // enables the timer
         captureStopwatch = new Stopwatch(); // initializes the stopwatch we use to make sure the camera is stable for long enough

         leadCamera.FrameReceived += FrameReceivedHandler; // register the frame received handler
         leadCamera.FocusCompleted += FocusCompletedHandler; // register the focus completed handler
         leadCamera.PictureReceived += PictureReceivedHandler; // register the picture received handler
      }

      protected override void OnAppearing()
      {
         base.OnAppearing();
         leadCamera.Camera.FocusMode = FocusMode.Continuous; // we're going to use continuous mode until we've found a document
      }

      private void PictureReceivedHandler(FrameHandlerEventArgs e)
      {
         // we received a picture!
         leadCamera.Camera.FocusMode = FocusMode.Continuous; // reset focus mode
         cameraFocused = false; // reset our focus flag
         autoCapture.Reset(); // reset autocapture values
         holding = false; // move out of "hold still" phase
         isCapturing = false; // we aren't waiting on any picture anymore
         shouldCheckStability = false; // we shouldn't check hold stability right away

         Device.BeginInvokeOnMainThread(() =>
         {
            stabilityLabel.Text = ""; // update label and display an alert
            DisplayAlert("Picture taken", "Took a picture", "Ok");
         });

         // TODO: do whatever you want with e.Image!

         e.Image.Dispose();
      }

      private void FocusCompletedHandler(Leadtools.Camera.Xamarin.FocusEventArgs e)
      {
         cameraFocused = true; // the camera is focused
      }

      private void FrameReceivedHandler(FrameHandlerEventArgs e)
      {
         if (e.Image == null) return; // make sure we actually have a frame to check
         if (!holding)
         {
            // if we AREN'T in "hold still" phase, let's check if the image is stable at all
            autoCapture.CheckStability(e.Image);
         }
         if (holding && shouldCheckStability)
         {
            // if we ARE in "hold still" phase and we need to check if we're still stable, let's do so
            // since shouldCheckStability is set to true every 300ms, this will only be reached once every 300ms

            shouldCheckStability = false; // reset the flag, we only need to do this once
            bool stable = autoCapture.CheckHoldStability(e.Image); // check the hold stability

            if (!stable) // if we're not stable, we need to move back out of "hold still" phase
            {
               holding = false; // move out of phase
               autoCapture.Reset(); // reset our autocapture
               captureStopwatch.Reset(); // reset the timer
               Device.BeginInvokeOnMainThread(() =>
               {
                  stabilityLabel.Text = ""; // reset our label
               });
               e.Image.Dispose();
               return;
            }
            else if (cameraFocused && captureStopwatch.ElapsedMilliseconds > 1500 && !isCapturing)
            {
               // image has been stable for a while (1500ms), image is focused, and we're not currently waiting on an image from the camera
               leadCamera.Camera.TakePicture();
               isCapturing = true; // make sure we don't call TakePicture() again until we've gotten our image from the camera
               Device.BeginInvokeOnMainThread(() =>
               {
                  stabilityLabel.Text = "Taking picture..."; // update our label to reflect that we're taking a picture
                  stabilityLabel.TextColor = Color.Green;
               });
            }
         }

         // if we AREN'T in "hold still" phase, but the camera is stable, let's move into "hold still" phase
         if (autoCapture.IsStable && !holding)
         {
            holding = true; // move in to "hold still"
            captureStopwatch.Reset(); // reset the capture stopwatch
            captureStopwatch.Start(); // start it so we can measure how long the camera has been stable
            cameraFocused = false; // reset focus flag
            leadCamera.Camera.FocusMode = FocusMode.Auto; // switch to auto mode so we can direct the camera to refocus manually
            leadCamera.Camera.Focus(); // tell camera to refocus
            Device.BeginInvokeOnMainThread(() =>
            {
               stabilityLabel.Text = "Hold still..."; // prompt user to hold still
               stabilityLabel.TextColor = Color.DarkOrange;
            });
         }

         e.Image.Dispose(); // release the frame
      }
   }
}

MainPage.xaml:
Code:

<?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:local="clr-namespace:AutoCaptureExample"
             xmlns:leadtools="clr-namespace:Leadtools.Camera.Xamarin;assembly=Leadtools.Camera.Xamarin"
             x:Class="AutoCaptureExample.MainPage">

   <StackLayout>
      <leadtools:CameraView x:Name="leadCamera" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
      <Label x:Name="stabilityLabel" FontSize="Large" HorizontalTextAlignment="Center"/>
   </StackLayout>
</ContentPage>


Attached is a sample project containing the page described in these snippets. When an image is captured, an alert dialog is displayed, but no further action is taken with the image.
File Attachment(s):
AutoCaptureExample.zip (379kb) downloaded 163 time(s).

Edited by moderator Thursday, March 19, 2020 10:09:46 AM(UTC)  | Reason: syntax highlighting

Joe Kerrigan
Intern
LEAD Technologies, Inc.
leadtools header
 

Try the latest version of LEADTOOLS for free for 60 days by downloading the evaluation: https://www.leadtools.com/downloads

Wanna join the discussion? Login to your LEADTOOLS Support accountor Register a new forum account.

You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2024, Yet Another Forum.NET
This page was generated in 0.076 seconds.