Skip to main content

Visual snap guidance | Android Document Scanner

To improve both the end user's experience and scanning quality you can add visual guidance to the scanning UI.

This will help the user understand the desired positioning, orientation, and size of the scanned document in the camera preview and take care of preliminary processing to better the results.

General idea#

In your layout put your finder view on top of ScanbotCameraView within the same parent, and specify it's id to ScanbotCameraView using app:finder_view_id="@id/my_finder_view_id" attribute:


<io.scanbot.sdk.ui.camera.ScanbotCameraXView    android:id="@+id/cameraView"    android:layout_width="match_parent"    android:layout_height="match_parent"    app:finder_view_id="@id/my_finder_view_id"/>
<io.scanbot.sdk.ui.camera.FinderOverlayViewandroid:id="@+id/my_finder_view_id"android:layout_width="match_parent"android:layout_height="match_parent"/>

Alternatively, you can just set id as android:id="@+id/finder_overlay" for your finder view and ScanbotCameraView will find it automatically.

Please note the following limitations when using finder view:

  • the parent view should not have any padding. ScanbotCameraView should have android:layout_width="match_parent" and android:layout_height="match_parent" layout parameters and no padding or margins;
  • the "Finder Overlay" view can have any margins, size, background or even child views, but it should always be over the camera preview frame, otherwise it will throw an IllegalStateException.

Not only will this direct the user's scanning process but also the FrameHandler, attached to given ScanbotCameraView will receive a non-null FrameHandler.Frame.finderRect object that will represent the frame area within the view finder's bounds. That can later be used, for example, for other SDK components that accept finder rect.

To start with: bare android.view.View (full customization)#

In case you want full control over the look and feel of the view finder - you can use any android.view.View subclass as a finder view. Take this example:

<io.scanbot.sdk.camera.ScanbotCameraView    android:id="@+id/camera_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    app:finder_view_id="@id/my_finder_view"/>
<Viewandroid:id="@+id/my_finder_view"android:layout_width="match_parent"android:layout_height="100dp"android:layout_gravity="bottom"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:layout_marginBottom="200dp"android:background="@drawable/finder_view_container_bg"/>

where @drawable/finder_view_container_bg is your xml-drawable with bounds outline. The result might look like this:

this.

FinderOverlayView - ready-to-use solution#

Instead of plain android.view.View you can use our specially made FinderOverlayView class. It handles all the hassle and leaves you with just a little bit of styling. Take this example:

<io.scanbot.sdk.camera.ScanbotCameraView    android:id="@+id/camera_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    app:finder_view_id="@id/my_finder_view"/>
<io.scanbot.sdk.ui.camera.FinderOverlayViewandroid:id="@+id/my_finder_view"android:layout_width="match_parent"android:layout_height="match_parent"/>

This component allows the following customizations:

  • overlay_color - color of area outside finder view gap
  • overlay_stroke_color - color of finder view border
  • stroke_width - width of finder view border
  • sbsdk_corner_radius - radius for rounded corners of finder view border
  • min_padding - minimum space between the finder view and screen borders
  • fixed_width - finder view's fixed width
  • fixed_height - finder view's fixed height

Alternatively, if you do not want to specify a fixed width and height, you can programmatically set the desired finder view aspect ratio. It will then take all the available screen space, respecting given aspect ratio and padding:

val requiredPageAspectRatios = listOf(FinderAspectRatio(85.60, 53.98)) // ~credit card size
...
val finderOverlayView = findViewById<FinderOverlayView>(R.id.finder_overlay_view)finderOverlayView.setRequiredAspectRatios(requiredPageAspectRatios)

The result might look like this:

this.

AdaptiveFinderOverlayView - for range of desired aspect ratios#

In case you are scanning different documents with different acceptable aspect ratios, but still want to preserve the logic of having a pre-selected rectangle of the document - you might use AdaptiveFinderOverlayView.

Take this example:

<io.scanbot.sdk.camera.ScanbotCameraView    android:id="@+id/camera_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    app:finder_view_id="@id/my_finder_view"/>
<io.scanbot.sdk.ui.camera.AdaptiveFinderOverlayViewandroid:id="@+id/my_finder_view"android:layout_width="match_parent"android:layout_height="match_parent"/>

AdaptiveFinderOverlayView uses ContourDetectorFrameHandler in its logic, so we also need to set that up:

val cameraView = findViewById<ScanbotCameraView>(R.id.camera_view)val finderOverlayView = findViewById<AdaptiveFinderOverlayView>(R.id.my_finder_view)
// we can use several aspect ratios:val pageAspectRatios = listOf( // this will be used for ContourDetectorFrameHandler        PageAspectRatio(21.0, 29.7), // a4 sheet size        PageAspectRatio(85.60, 53.98)) // credit card sizeval finderAspectRatios = pageAspectRatios.toFinderAspectRatios() // for AdaptiveFinderOverlayViewmyFinderOverlayView.setRequiredAspectRatios(finderAspectRatios)
val contourDetectorFrameHandler = ContourDetectorFrameHandler.attach(cameraView, scanbotSDK.createContourDetector())contourDetectorFrameHandler.setRequiredAspectRatios(pageAspectRatios)contourDetectorFrameHandler.addResultHandler(finderOverlayView.contourDetectorFrameHandler)

Now during live detection the finder view will adjust its borders to a detected document if it complies to one of the aspect ratios set.

ZoomFinderOverlayView - help your user to "aim" better#

For rare cases when your app is to be used for scanning very small pieces of data (e.g. those tiny barcodes on eye drop bottles) you can enhance that experience by zooming in the preview.

This can be achieved by using ZoomFinderOverlayView finder view. It is a successor of FinderOverlayView offering all the same customization with additional ability to set the zoom level.

info

This view does not operate optical zoom of device's camera module, it only scales the preview so that things appear bigger. Consider this to be digital zoom.

First, just add it to the view hierarchy as you would do with any other finder view mentioned above:


<io.scanbot.sdk.camera.ScanbotCameraView    android:id="@+id/cameraView"    android:layout_width="match_parent"    android:layout_height="match_parent"/>
<io.scanbot.sdk.ui.camera.ZoomFinderOverlayViewandroid:id="@id/finder_overlay"android:layout_width="match_parent"android:layout_height="match_parent"app:fixed_height="25dp"/>    

app:fixed_height="25dp" attribute here sets the desired finder height when zoomed out (default state, zoomLevel value equals 1.0f). Combined with the ability to set FinderAspectRatio you can achieve the desired look and feel for this view.

When requested (e.g. by user pressing a button) you can zoom in this view by programmatically setting zoom level:

myFinderView.zoomLevel = 1.5f

You can set a higher value as you like - there is no maximum. In fact, the actual zoom set will be automatically calculated according to your layout's bounds and might be smaller than requested.

If your screen has additional views that need to be adjusted together with preview zoomed in, you can add UiZoomDelegate instance to finder view with your custom logic defined:

myFinderView.addCameraZoomDelegate { actualZoomLevel: Float ->    myViewAlsoNeedsZoom.scaleX = actualZoomLevel    myViewAlsoNeedsZoom.scaleY = actualZoomLevel}