web-dev-qa-db-ja.com

SurfaceViewに長方形を描く

特定の位置とサイズで長方形を描く方法を知りたいのですが。

こことWebでいくつかの試行と例を試しましたが、何もうまくいきませんでした。

私はSurfaceViewとSurfaceHolderを使用してカメラのプレビューを保持しています。

ユーザーが画面をタッチしたときに長方形を描きたいだけです。

外部ライブラリを使用したくないのですが、ホルダーからキャンバスを取得しようとするとnullになります。

今のところコードはありません。私には何も機能しません。誰かがそれを行う方法の手がかりを持っているなら、私はそれを試してみます。

これは私がすでに試したことです:

リンク1

リンク2

リンク

手伝ってくれてありがとう!

7
user2235615

わかりました、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);
    }

最後に、「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);
}

ご覧のとおり、毎回キャンバスをクリアします。これを行わないと、サーフェスにさらに長方形が表示されます。

これは、「OnTouchListener」イベントからこのメソッドを呼び出す方法です。

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

これが他の誰かに役立つことを願っています。

7
user2235615

新しいサーフェスをカスタマイズし、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"/>
2
user9674050