5

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() {....}
Abhishek Lahiri
  • 123
  • 1
  • 7

1 Answers1

5

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

Saurabh Thorat
  • 18,131
  • 5
  • 53
  • 70
  • Thanks Saurabh. This is very helpful. I am a bit new to this, could you help clarify, why this works and not the usual methods of drawing on a canvas per se? – Abhishek Lahiri Jul 27 '20 at 05:52
  • `PreviewView` is a `ViewGroup`, and `SurfaceView` is a `View`. By default, `onDraw()` of `ViewGroup` is not called. So all the drawing is delegated to its children. So you have to use custom view like `RectOverlay` to draw it for you. – Saurabh Thorat Jul 27 '20 at 06:31