2017년 10월 7일 토요일

transparent canvas in Android Camera (Overlay) (카메라 Preview위에 그림 그리기)


카메라 Preview위에 그림 그리기

1. 들어가기에 앞서

카메라 Preview 위에 정보를 덧씌우는 기능이 필요로 하는 경우가 있습니다.
이전 카메라 Preview 하기 소스를 기본 바탕으로 합니다.
https://swlock.blogspot.com/2017/09/android-camera.html

2. 관련자료

stackoverflow에서 관련 내용을 찾았습니다.
https://stackoverflow.com/questions/44208122/android-camera2-api-textureview-overlay-for-drawing-on-camera-preview

해당 내용은, 카메라가 TextureView로 동작하고 있으며 그 위에 SurfaceView를 만들고(CustomView extends SurfaceView) SurfaceView의 투과 속성을 주어 Overlay 되는 방식입니다.
막상 해보면 전체 소스를 제공하지 않아서, 많은 시간을 투자했지만 어떤 부분을 잘못 했는지 제대로 동작되지 않았습니다.

3. 변경된 작업들

stackoverflow에 있는 CustomView의 내용, SurfaceView를 일반 View로 변경하였습니다.
CustomView extends SurfaceView -> CustomView extends View
또한 onTouchEvent 함수 내부를 전체적으로 변경하였습니다.

CameraPreview가 되는 TextureView아래쪽에 RelativeLayout을 배치 합니다. 꼭 RelativeLayout이 아니어도 되지만, 위젯 배치의 Z-order상 TextureView 다음에 배치가 되도록 합니다.
    <com.darts.pv.cam.camerapreivew.AutoFitTextureView
        android:id="@+id/texture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true" />

    <RelativeLayout android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        />

RelativeLayout에 CustomView를 연결합니다.
RelativeLayout surface = (RelativeLayout)view.findViewById(R.id.view);
surface.addView(new CustomView(this));

onDraw에서 전체적으로 Canvas에 그림을 그리게 되므로, 버튼을 누르면 ex,ey라는 변수로 누른 지점을 저장합니다.
1초 후에는 mFocus flag를 off 함으로서 Canvas에 아무것도 그려지지 않도록 합니다.

public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        if( !mFocus ) {
            new Handler().postDelayed(new Runnable() {
                @Override                public void run() {
                    mFocus = false;
                    invalidate();
                }
            }, 1000);
        }
        mFocus = true;
        ex = event.getX();
        ey = event.getY();

기본적으로는 view가 투과되도록 색을 설정합니다.
setBackgroundColor(Color.TRANSPARENT);

Focus가 있는경우 onDraw에서 그려질 수 있도록 합니다.
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if( mFocus ){
        canvas.drawCircle(ex, ey, 100, paint);
    }
}

4. 작업된 전체 소스

https://drive.google.com/open?id=0B9vAKDzHthQINXpJczA3MnkxN1U

5. 동작 화면

화면을 누르면 동그란 원이 1초 정도 나왔다가 사라집니다. 아래 화면에서 흰색 동그란 원입니다.


댓글 없음:

댓글 쓰기