package com.af.experiments.FxCameraApp.View; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Rect; import android.hardware.Camera; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import com.af.experiments.FxCameraApp.camera.CameraHelper; import java.io.IOException; public class DefaultPreview extends SurfaceView implements CameraView.Preview, Camera.PictureCallback, GestureDetector.OnGestureListener { private static final String TAG = "DefaultPreview"; private CameraHelper mCameraHelper; private GestureDetector mGestureDetector; public DefaultPreview(final Context context) { super(context); initialize(context); } public DefaultPreview(final Context context, final AttributeSet attrs) { super(context, attrs); initialize(context); } public DefaultPreview(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); initialize(context); } @SuppressWarnings("deprecation") private void initialize(final Context context) { mGestureDetector = new GestureDetector(context, this); getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override public void setCameraHelper(final CameraHelper helper) { mCameraHelper = helper; } @Override public boolean isSquareFrameSupported() { return false; } @Override public void onOpenCamera() { } @Override public void onReleaseCamera() { } @Override public void startPreview(final int measurePreviewWidth, final int measurePreviewHeight, final CameraView.CameraStateListener listener) { if (measurePreviewWidth > 0 && measurePreviewHeight > 0) { mCameraHelper.setupOptimalPreviewSizeAndPictureSize(measurePreviewWidth, measurePreviewHeight, 0); } requestLayout(); mCameraHelper.setDisplayOrientation(mCameraHelper.getOptimalOrientation()); try { mCameraHelper.setPreviewDisplay(getHolder()); } catch (IOException e) { Log.e(TAG, "IOException caused by setPreviewDisplay()", e); throw new IllegalStateException(e.getMessage(), e); } mCameraHelper.startPreview(); if (listener != null) { listener.onStartPreview(); } } @Override public void onStopPreview() { } private CameraView.CaptureCallback mCaptureCallback; @Override public void takePicture(final CameraView.CaptureCallback callback) { takePicture(callback, true); } @Override public void takePicture(final CameraView.CaptureCallback callback, final boolean autoFocus) { mCaptureCallback = callback; mCameraHelper.takePicture(this, autoFocus); } @Override public void onPictureTaken(final byte[] data, final Camera camera) { mCameraHelper.stopPreview(); final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); if (!mCaptureCallback.onImageCapture(bitmap) && bitmap != null) { bitmap.recycle(); } mCaptureCallback = null; } @Override public boolean onTouchEvent(final MotionEvent event) { return mGestureDetector.onTouchEvent(event); } @Override public boolean onDown(final MotionEvent e) { return false; } @Override public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX, final float velocityY) { return false; } @Override public void onLongPress(final MotionEvent e) { onTap(e); } @Override public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX, final float distanceY) { return false; } @Override public void onShowPress(final MotionEvent e) { } @Override public boolean onSingleTapUp(final MotionEvent e) { return onTap(e); } ////////////////////////////////////////////////////////////////////////// private static final int AREA_SIZE = 2000; private static final int AREA_HALF_SIZE = AREA_SIZE / 2; private static final int DEFAULT_AREA_WEIGHT = 1000; private boolean onTap(final MotionEvent event) { boolean result = false; if (event.getAction() == MotionEvent.ACTION_DOWN) { final double x = event.getX() / getWidth() * AREA_SIZE - AREA_HALF_SIZE; final double y = event.getY() / getHeight() * AREA_SIZE - AREA_HALF_SIZE; final int angle = mCameraHelper.getOrientation() * -1; final int x2 = Math.min(Math.max((int) Math.round(x * Math.cos(angle) - y * Math.sin(angle)), -AREA_HALF_SIZE), AREA_HALF_SIZE); final int y2 = Math.min(Math.max((int) Math.round(x * Math.sin(angle) + y * Math.cos(angle)), -AREA_HALF_SIZE), AREA_HALF_SIZE); final int size = (int) Math.max(event.getSize() / 2, 10); final CameraHelper.AreaCompat area = new CameraHelper.AreaCompat(new Rect( Math.max(x2 - size, -AREA_HALF_SIZE), Math.max(y2 - size, -AREA_HALF_SIZE), Math.min(x2 + size, AREA_HALF_SIZE), Math.min(y2 + size, AREA_HALF_SIZE) ), DEFAULT_AREA_WEIGHT); if (mCameraHelper.getMaxNumFocusAreas() > 0) { mCameraHelper.setFocusAreas(area); result = true; } if (mCameraHelper.getMaxNumMeteringAreas() > 0) { mCameraHelper.setMeteringAreas(area); result = true; } } return result; } }