在SurfaceView上绘制矩形

时间:2014-09-18 08:21:06

标签: android-camera surfaceview

我想知道如何绘制特定位置和大小的矩形。

我在这里和网上尝试了几个试验和例子,但没有任何对我有用。

我正在使用SurfaceView和SurfaceHolder来保存相机预览。

我只想在用户触摸屏幕时绘制一个矩形。

我不想使用外部库,当我试图从持有者那里获取画布时,我将变为空。

现在没有代码,对我没什么用,如果有人知道怎么做,我会试试。

这是我已经尝试过的:

Link 1

Link 2

Link 3

感谢您的帮助!

2 个答案:

答案 0 :(得分:6)

好的,感谢fadden,我找到了最简单的解决方案(至少对我而言)。

首先我创建了另一个Surface视图,我的XML文件如下所示:

<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>

而且我为新表面创建了另一个持有者,这是我的java代码的一部分:

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);
    }

最后,我实现了一个名为&#39; DrawFocusRect&#39;

的方法
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);
}

正如你所看到的,我每次都清理画布,如果我不这样做,表面会另外显示更多的矩形。

这是我通过OnTouchListener&#39;来调用此方法的方法。事件:

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);
             }
         };

希望这对其他人有帮助。

答案 1 :(得分:2)

我自定义一个新曲面并使用onTouchEvent并绘制我的矩形:

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;
    }

用于绘制矩形使用此函数:

    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;
    }
}

现在,您可以在XML文件中使用此自定义表面,如下所示:

<com.glinter.ir.MySurface 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>