Search code examples
android-camerasurfaceview

Draw Rectangle on SurfaceView


I would like to know how to draw a rectangle in specific position and size.

I tried a couple of trials and examples here and on web, but nothing worked for me.

I'm using a SurfaceView and SurfaceHolder to hold the camera preview.

I just want to draw a rectangle when the user touch on the screen.

I don't want to use external library and When I'm trying to get the canvas from the holder I'm getting null.

For now there is no code, cause nothing work for me, if someone has a clue how to do it, I will try it.

This is what I've already tried:

Link 1

Link 2

Link 3

Thanks for help!


Solution

  • Ok, Thanks to fadden I found the easiest solution(at least for me).

    First I created another Surface view and my XML file look like this:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/scrollView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:opencv="http://schemas.android.com/apk/res-auto"
        android:layout_gravity="left|top">
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical" >
    
                        <SurfaceView
                            android:layout_alignParentTop="true"
                            android:id="@+id/CameraView"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent" />
                        <SurfaceView
                            android:layout_alignParentTop="true"
                            android:id="@+id/TransparentView"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent" />
               </RelativeLayout>
    </RelativeLayout>
    

    And than I'm created another holder for the new surface, this is a part of my java code:

    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_video_capture);
            // Create first surface with his holder(holder)
            cameraView = (SurfaceView)findViewById(R.id.CameraView);
            cameraView.setOnTouchListener(onTouchListner);
    
            holder = cameraView.getHolder();
            holder.addCallback(this);
            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    
            // Create second surface with another holder (holderTransparent)
            transparentView = (SurfaceView)findViewById(R.id.TransparentView);
    
            holderTransparent = transparentView.getHolder();
            holderTransparent.setFormat(PixelFormat.TRANSPARENT);
            holderTransparent.addCallback(callBack); 
            holderTransparent.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    

    At last I implement a method called 'DrawFocusRect'

    private void DrawFocusRect(float RectLeft, float RectTop, float RectRight, float RectBottom, int color)
    {
    
        canvas = holderTransparent.lockCanvas();
        canvas.drawColor(0,Mode.CLEAR);
        //border's properties
        paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(color);
        paint.setStrokeWidth(3);
        canvas.drawRect(RectLeft, RectTop, RectRight, RectBottom, paint);
    
    
        holderTransparent.unlockCanvasAndPost(canvas);
    }
    

    As you can see, I clear the canvas every time, if I don't do this, the surface will display in addition more rectangles on each others.

    This is how I call to this method from a 'OnTouchListener' event:

    OnTouchListener onTouchListner = new OnTouchListener() {
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                        RectLeft = event.getX() - 100;
                        RectTop = event.getY() - 100 ;
                        RectRight = event.getX() + 100;
                        RectBottom = event.getY() + 100;
                        DrawFocusRect(RectLeft , RectTop , RectRight , RectBottom , Color.BLUE);
                 }
             };
    

    Hope this would be helpfull for someone else.