Skip to content
On this page

Creating a Preview for the User

As part of your application, it is recommended to present the user with a camera preview, as it helps the user to center his face on the camera. It also allows for the presentation of a face detection bounding graphic (such as a rectangle or oval shape) on the screen.

The following code can be used to create a preview and present a face detection bounding graphic to the user.

1. Create a TextureView element in your XML

The aspect ratio of the images received from the SDK is 4:3. In order to present a preview in the application, a TextureView element should be added to the screen XML layout file. In order to preserve the same aspect ratio in the UI and prevent image distortion, the TextureView element is configured with app:layout_constraintDimensionRatio="W, 4:3".

For example, see the TextureView configuration below:

XML
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextureView
                android:id="@+id/cameraView"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintDimensionRatio="W, 4:3"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

2. Receive images from the SDK

Images are received from the SDK on a background thread. The application must switch to the UI thread in order to perform UI changes.

Kotlin
override fun onImage(imageData: ImageData) {
    runOnUiThread {
        handleImageData(imageData)
    }
}
Java
public void onImage(ImageData imageData) {
    runOnUiThread(() -> {
        handleImageData(imageData)
    });
}

3. Draw the image and face detection bounding graphic on the TextureView

In this code example, faceDetectionBitmap is a Bitmap asset of the app.

Kotlin
fun handleImageData(imageData: ImageData) {
    binding.cameraView.lockCanvas()?.let { canvas ->
        // Drawing the bitmap on the TextureView canvas
        val image = imageData.image
        canvas.drawBitmap(
            image,
            null,
            Rect(0, 0, binding.cameraView.width, binding.cameraView.bottom - binding.cameraView.top),
            null
        )

        // Drawing the face detection bounding rectangle (if not null..)
        imageData.roi?.let roi@{ faceDetectionRect ->
            // First, scale the SDK face detection rectangle to fit the TextureView size
            val targetRect = RectF(faceDetectionRect)
            val m = Matrix()
            m.postScale(1f, 1f, image.width / 2f, image.height / 2f)
            m.postScale(
                binding.cameraView.width.toFloat() / image.width.toFloat(),
                binding.cameraView.height.toFloat() / image.height.toFloat()
            )
            m.mapRect(targetRect)
            // Then, draw it on the canvas
            canvas.drawBitmap(faceDetectionBitmap ?: return@roi, null, targetRect, null)
        }

        binding.cameraView.unlockCanvasAndPost(canvas)
    }
}
Java
public void onImage(ImageData imageData) {
    // Drawing the bitmap on the TextureView canvas
    Bitmap image = imageData.getImage();
    canvas.drawBitmap(
            image,
            null,
            new Rect(0, 0, mBinding.cameraView.getWidth(),
                    mBinding.cameraView.getBottom() - mBinding.cameraView.getTop()),
            null
    );

    //Drawing the face detection (if not null..)
    Rect roi = imageData.getROI();
    if (roi != null) {
        //First we scale the SDK face detection rectangle to fit the TextureView size
        RectF targetRect = new RectF(roi);
        Matrix m = new Matrix();
        m.postScale(1f, 1f, image.getWidth() / 2f, image.getHeight() / 2f);
        m.postScale(
                (float)mBinding.cameraView.getWidth() / image.getWidth(),
                (float)mBinding.cameraView.getHeight() / image.getHeight()
        );
        m.mapRect(targetRect);
        // Then we draw it on the Canvas
        canvas.drawBitmap(faceDetectionBitmap, null, targetRect, null);
    }

    mBinding.cameraView.unlockCanvasAndPost(canvas);
}

Info

For a complete example of an application preview please refer to the Sample Application code.