Search code examples
androidxandroid-camerax

How to draw on PreviewView?


I have a PreviewView instance on which i want to draw a rect based on object identifies using Firebase and Image Analyser use case.

However, unlike in Text/ SurfaceView PreviewView doesn't let any Canvas to be drawn on top of it.

What's the alternative?

Further Edits:

Tried the below earlier:

Canvas objectFrameCanvas = new Canvas();
Paint pen = new Paint();
pen.setColor(Color.RED);
pen.setStrokeWidth(8F);
pen.setStyle(Paint.Style.STROKE);

objectFrameCanvas.drawRect(100,150,200, 250, pen);

TextureView textureView = new TextureView(this);
textureView.draw(objectFrameCanvas);

mPreviewView.addView(textureView);

Create a child forviewgroup : textureView. Make new canvas objectFrameCanvas, draw rectangle on it, then draw canvas on textureView. Then add this to view group (PreviewView)

Still doesnt give me the requisite result it should.

By the way am using this inside my ImageAnanysis usecase

imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {....}

Solution

  • To draw on top of your preview, you can create a custom view which draws a rectangle with the list of RectF you give it. Here's a gist of it:

    class RectOverlay constructor(context: Context?, attributeSet: AttributeSet?) :
        View(context, attributeSet) {
    
        override fun onDraw(canvas: Canvas) {
            super.onDraw(canvas)
            // Pass it a list of RectF (rectBounds)
            rectBounds.forEach { canvas.drawRect(it, paint) }
        }
    }
    

    And use this custom view in your layout:

    <androidx.constraintlayout.widget.ConstraintLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <androidx.camera.view.PreviewView
            android:id="@+id/preview_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <com.example.RectOverlay
            android:id="@+id/rect_overlay"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    Here is a good repo to check which uses CameraX and draws rectangular bounds over detected faces: https://github.com/husaynhakeem/android-playground/tree/master/FaceDetectorSample