Back to project page FxCameraApp.
The source code is released under:
MIT License
If you think the Android project FxCameraApp listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.af.experiments.FxCameraApp.View; /* w w w. ja v a 2 s . c o m*/ import android.content.Context; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Point; import android.hardware.Camera; import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import com.af.experiments.FxCameraApp.camera.CameraHelper; import com.af.experiments.FxCameraApp.camera.CameraHelperFactory; import com.af.experiments.FxCameraApp.display.DisplayHelperFactory; import com.af.experiments.FxCameraApp.ogles.PreviewSurfaceHelper; import com.af.experiments.FxCameraApp.ogles.PreviewSurfaceHelperFactory; import java.io.IOException; public class CameraView extends ViewGroup implements SurfaceHolder.Callback { public interface Preview { void setCameraHelper(CameraHelper helper); boolean isSquareFrameSupported(); void onOpenCamera(); void onReleaseCamera(); void startPreview(int measurePreviewWidth, int measurePreviewHeight, CameraStateListener l); void onStopPreview(); void takePicture(CaptureCallback callback); void takePicture(CaptureCallback callback, boolean autoFocus); } public static enum PreviewSizePolicy { DISPLAY, VIEW, PREVIEW, MANUAL } public interface CameraStateListener { void onOpenCamera(); void onStartPreview(); void onReleaseCamera(); } public interface OnErrorListener { static final int ERROR_UNKNOWN = -1; static final int ERROR_CAMERA_INITIAL_OPEN = 0; void onError(int error, Exception e, CameraView view); } public interface CaptureCallback { boolean onImageCapture(Bitmap bitmap); } private static final String TAG = "CameraView"; private CameraHelper mCameraHelper; private PreviewSurfaceHelper mPreviewSurfaceHelper; private Preview mPreview; private boolean mUsePreviewCallback; private SurfaceView mPushBufferSurface; private boolean mAutoStart = true; private boolean mPreviewAlignCenter; private boolean mSquareFrame; private View mOverlayView; private PreviewSizePolicy mPreviewSizePolicy = PreviewSizePolicy.DISPLAY; private CameraStateListener mCameraStateListener; private OnErrorListener mOnErrorListener; public CameraView(final Context context) { super(context); initialize(context); } public CameraView(final Context context, final AttributeSet attrs) { super(context, attrs); initialize(context); } public CameraView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); initialize(context); } private void initialize(final Context context) { mCameraHelper = CameraHelperFactory.newCameraHelper(context); mPreviewSurfaceHelper = PreviewSurfaceHelperFactory.newPreviewSurfaceHelper(mCameraHelper); setPreview(new DefaultPreview(context), false); //setPreview(new GlPreview(context)); } @Override protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) { final int width = r - l; final int height = b - t; final int count = getChildCount(); View preview = null; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child != null) { if (child.equals(mPreview)) { int childWidth = width - getPaddingLeft() - getPaddingRight(); int childHeight = height - getPaddingTop() - getPaddingBottom();; if (mPreview.isSquareFrameSupported() && mSquareFrame) { final int size = Math.min(childWidth, childHeight); childWidth = size; childHeight = size; } else if (mCameraHelper.isOpened()) { final Camera.Size previewSize = mCameraHelper.getPreviewSize(); if (previewSize != null) { final int previewWidth; final int previewHeight; switch (getResources().getConfiguration().orientation) { case Configuration.ORIENTATION_PORTRAIT: previewWidth = previewSize.height; previewHeight = previewSize.width; break; default: previewWidth = previewSize.width; previewHeight = previewSize.height; break; } final double scale = Math.min((double) childWidth / (double) previewWidth, (double) childHeight / (double) previewHeight); childWidth = (int) Math.floor(previewWidth * scale); childHeight = (int) Math.floor(previewHeight * scale); } } final int childLeft; final int childTop; if (mPreviewAlignCenter) { childLeft = (width - childWidth) / 2; childTop = (height - childHeight) / 2; } else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { childLeft = (width - childWidth) / 2; childTop = 0; } else { childLeft = 0; childTop = (height - childHeight) / 2; } child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight); preview = child; break; } } } if (preview != null) { if (mPushBufferSurface != null) { mPushBufferSurface.layout(preview.getLeft(), preview.getTop(), preview.getRight(), preview.getBottom()); } if (mOverlayView != null) { mOverlayView.layout(preview.getLeft(), preview.getTop(), preview.getRight(), preview.getBottom()); } } } @Override public void removeAllViews() { mOverlayView = null; super.removeAllViews(); } @Override public void removeView(final View view) { if (mOverlayView != null && mOverlayView.equals(view)) { mOverlayView = null; } super.removeView(view); } @Override public void removeViewAt(final int index) { final View view = getChildAt(index); if (mOverlayView != null && mOverlayView.equals(view)) { mOverlayView = null; } super.removeViewAt(index); } @Override public void surfaceCreated(final SurfaceHolder holder) { try { openCamera(mCameraHelper.getCameraId()); } catch (final RuntimeException e) { if (mOnErrorListener != null) { mOnErrorListener.onError(OnErrorListener.ERROR_CAMERA_INITIAL_OPEN, e, this); } else { throw e; } } } @Override public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) { if (!mCameraHelper.isOpened()) { return; } if (mUsePreviewCallback) { try { mPreviewSurfaceHelper.setPreviewDisplay(holder); } catch (IOException e) { Log.e(TAG, "IOException caused by setPreviewDisplay()", e); throw new IllegalStateException(e.getMessage(), e); } } if (mAutoStart) { startPreview(); } } @Override public void surfaceDestroyed(final SurfaceHolder holder) { releaseCamera(); } public CameraHelper getCameraHelper() { return mCameraHelper; } public Preview getPreview() { return mPreview; } public void setPreview(final Preview preview) { setPreview(preview, preview != null && !(preview instanceof DefaultPreview)); } public void setPreview(final Preview preview, final boolean usePreviewCallback) { removePreview(); mUsePreviewCallback = usePreviewCallback; if (preview != null) { if (preview instanceof SurfaceView) { final SurfaceView surface = (SurfaceView) preview; if (usePreviewCallback) { mPushBufferSurface = mPreviewSurfaceHelper.createPushBufferSurfaceViewIfNeed(getContext()); } if (mPushBufferSurface != null) { mPushBufferSurface.getHolder().addCallback(this); mPreviewSurfaceHelper.setZOrderMediaOverlay(surface); } else { surface.getHolder().addCallback(this); } addView(surface, 0); if (mPushBufferSurface != null) { addView(mPushBufferSurface, 0); } } else { //throw new IllegalArgumentException(); } mPreview = preview; mPreview.setCameraHelper(mCameraHelper); } } public void removePreview() { if (mPreview != null) { if (mPreview instanceof SurfaceView) { final SurfaceView surface = (SurfaceView) mPreview; surface.getHolder().removeCallback(this); } if (mPreview instanceof View) { final View view = (View) mPreview; removeView(view); } mPreview.setCameraHelper(null); mPreview = null; } if (mPushBufferSurface != null) { mPushBufferSurface.getHolder().removeCallback(this); removeView(mPushBufferSurface); mPushBufferSurface = null; } mUsePreviewCallback = false; } public boolean isAutoStart() { return mAutoStart; } public void setAutoStart(final boolean autoStart) { mAutoStart = autoStart; } public boolean isPreviewAlignCenter() { return mPreviewAlignCenter; } public void setPreviewAlignCenter(final boolean previewAlignCenter) { mPreviewAlignCenter = previewAlignCenter; requestLayout(); } public boolean isSquareFrame() { return mSquareFrame; } public void setSquareFrame(final boolean square) { if (mSquareFrame != square) { mSquareFrame = square; requestLayout(); } } public void setOverlayView(final View child) { if (mOverlayView != null) { removeView(mOverlayView); } mOverlayView = child; if (mOverlayView != null) { addView(child); } } public View getOverlayView() { return mOverlayView; } public PreviewSizePolicy getPreviewSizePolicy() { return mPreviewSizePolicy; } public void setPreviewSizePolicy(final PreviewSizePolicy previewSizePolicy) { if (previewSizePolicy == null) { throw new IllegalArgumentException("PreviewSizePolicy must not be null"); } mPreviewSizePolicy = previewSizePolicy; } public void setCameraStateListener(final CameraStateListener callback) { mCameraStateListener = callback; } public void setOnErrorListener(final OnErrorListener l) { mOnErrorListener = l; } public void switchCamera(final int cameraId) { openCamera(cameraId); startPreview(); } private void openCamera(final int cameraId) { synchronized (this) { mCameraHelper.openCamera(cameraId); mPreview.onOpenCamera(); if (mCameraStateListener != null) { mCameraStateListener.onOpenCamera(); } } } private void releaseCamera() { stopPreview(); synchronized (this) { if (mCameraStateListener != null) { mCameraStateListener.onReleaseCamera(); } mCameraHelper.releaseCamera(); mPreview.onReleaseCamera(); } } public void startPreview() { stopPreview(); synchronized (this) { if (mCameraHelper.isOpened()) { int width; int height; switch (mPreviewSizePolicy) { case DISPLAY: { final Point point = DisplayHelperFactory.newDisplayHelper(getContext()).getRawDisplaySize(); width = point.x; height = point.y; } break; case VIEW: { width = getWidth(); height = getHeight(); } break; case PREVIEW: { final View view = (View) mPreview; width = view.getWidth(); height = view.getHeight(); } break; case MANUAL: { width = 0; height = 0; } break; default: throw new IllegalStateException("Unsupported PreviewSizePolicy type " + mPreviewSizePolicy.toString()); } mPreview.startPreview(width, height, mCameraStateListener); } } } public void stopPreview() { synchronized (this) { mCameraHelper.stopPreview(); mPreview.onStopPreview(); } } public void capture(final CameraView.CaptureCallback callback) { capture(callback, true); } public void capture(final CameraView.CaptureCallback callback, final boolean autoFocus) { mPreview.takePicture(callback, autoFocus); } }