Draw Rectangle on SurfaceView

前端 未结 2 1283
情歌与酒
情歌与酒 2021-01-31 23:46

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

相关标签:
2条回答
  • 2021-01-31 23:57

    I customize a new surface and using onTouchEvent and draw my rectangle:

    public class MySurface extends SurfaceView {
        private Paint mPaint;
        private Path mPath;
        private Canvas mCanvas;
        private SurfaceHolder mSurfaceHolder;
        private float mX, mY, newX, newY;
    
        public MSurface(Context context) {
            super(context);
            initi(context);
        } 
    
        private void initi(Context context) { 
            mSurfaceHolder = getHolder();
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setTextSize(12);
            mPaint.setColor(Color.RED);
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
    
                case MotionEvent.ACTION_DOWN:
                    mX = event.getX();
                    mY = event.getY(); 
                    break;
                case MotionEvent.ACTION_MOVE:
                    newX = event.getX();
                    newY = event.getY(); 
                    break; 
                default:
                    // Do nothing
            }
            drawRect();
            invalidate();
            return true;
        }
    

    for drawing your rectangle use this function:

        private void drawRect() {
            mPath = new Path();
            mPath.moveTo(mX, mY);
            mCanvas = mSurfaceHolder.lockCanvas();
            mCanvas.save(); 
            mPath.addRect(mX, mY, newX, newY, Path.Direction.CCW);
            mCanvas.drawPath(mPath, mPaint); 
            mCanvas.restore();
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            mX = newX;
            mY = newY;
        }
    }
    

    Now you can use this customized surface in your XML files as below:

    <com.glinter.ir.MySurface 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    
    0 讨论(0)
  • 2021-02-01 00:10

    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.

    0 讨论(0)
提交回复
热议问题