花门楼前见秋草,岂能贫贱相看老。这篇文章主要讲述Android Camera2 拍照——切换摄像头,延时拍摄和闪光模式相关的知识,希望能为你提供帮助。
原文:Android Camera2 拍照(三)——切换摄像头,延时拍摄和闪光模式【Android Camera2 拍照——切换摄像头,延时拍摄和闪光模式】一、切换摄像头在前后摄像头之间切换,首先需要关闭之前打开的摄像头,关闭preview,之后重新打开新的摄像头,重新打开preview。
public void switchCamera() { if (mCameraId.equals(CAMERA_FRONT)) { mCameraId = CAMERA_BACK; closeCamera(); reopenCamera(); } else if (mCameraId.equals(CAMERA_BACK)) { mCameraId = CAMERA_FRONT; closeCamera(); reopenCamera(); } }
关闭摄像头:
/** * Closes the current {@link CameraDevice}. */ private void closeCamera() { try { mCameraOpenCloseLock.acquire(); synchronized (mCameraStateLock) {// Reset state and clean up resources used by the camera. // Note: After calling this, the ImageReaders will be closed after any background // tasks saving Images from these readers have been completed. mPendingUserCaptures = 0; mState = STATE_CLOSED; if (null != mCaptureSession) { mCaptureSession.close(); mCaptureSession = null; } if (null != mCameraDevice) { mCameraDevice.close(); mCameraDevice = null; } if (null != mJpegImageReader) { mJpegImageReader.close(); mJpegImageReader = null; } if (null != mRawImageReader) { mRawImageReader.close(); mRawImageReader = null; } } } catch (InterruptedException e) { throw new RuntimeException("Interrupted while trying to lock camera closing.", e); } finally { mCameraOpenCloseLock.release(); } }
打开新的摄像头:
public void reopenCamera() { if (mTextureView.isAvailable()) { openCamera(); } else { mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); } }
如果TextureView是available的,那么直接调用openCamera()打开camera(openCamera()的代码参考之前的博客);如果|TextureView是unavailable的,那么调用TextureView的setSurfaceTextureListener设置SurfaceTextureListener(参考上一篇博客)。 二、延时拍摄要实现延时拍摄,核心是实现一个定时器。本例延时分为三种模式:3s延时,10s按时,无延时。可以在三种模式之中自有切换。
private void switchDelayState() { switch (mDelayState) { case 0: mTimer.setImageResource(R.mipmap.ic_3s); mDelayTime = 3 * 1000; mDelayState = 1; break; case 1: mTimer.setImageResource(R.mipmap.ic_10s); mDelayTime = 10 * 1000; mDelayState = 2; break; case 2: mTimer.setImageResource(R.mipmap.timer); mDelayTime = 0; mDelayState = 0; break; default: break; } }
变量mDelayTime和mDelaySate的定义:
/* * Delay state, 0 represents no delay, 1 represents 3s delay, while 2 represents 10s delay */ private short mDelayState = 0; // Timer private short mDelayTime;
当拍摄按钮被点击时:
@Override public void onClick(View view) { switch (view.getId()) { case R.id.capture: { if (mDelayState == 0) { takePicture(); } else { new CountDownTimer(mDelayTime, TIME_INTERVAL) { @Override public void onTick(long millisUntilFinished) { mTimeText.setVisibility(View.VISIBLE); mTimeText.setText("" + millisUntilFinished / TIME_INTERVAL); }@Override public void onFinish() { mTimeText.setVisibility(View.GONE); takePicture(); } }.start(); } break; }
但有3s或10s延时的时候,利用CountDownTimer实现倒计时并每隔一秒更新剩余时间提示,到时候执行拍照功能。 三、切换闪光模式支持自动,强制,禁止闪光。与闪光模式有关的属性是CaptureRequest.CONTROL_AE_MODE和CaptureRequest.FLASH_MODE。 如果要使用FLASH_MODE属相,闪光灯必须可用,并且,CONTROL_AE_MODE必须设置为on或off,否则,自动曝光属性的ON_AUTO_FLASH,ON_ALWAYS_FLASH, ON_AUTO_FLASH_REDEYE将会覆盖FLASH_MODE的设置。
private void switchFlashMode() { switch (mFlashMode) { case 0: mFlashMode = 1; mFlashBtn.setImageResource(R.mipmap.flash_auto); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); try { mCaptureSession.setRepeatingRequest( mPreviewRequestBuilder.build(), mPreCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); return; }break; case 1: mFlashMode = 2; mFlashBtn.setImageResource(R.mipmap.flash_on); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); try { mCaptureSession.setRepeatingRequest( mPreviewRequestBuilder.build(), mPreCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); return; } break; case 2: mFlashMode = 0; mFlashBtn.setImageResource(R.mipmap.flash_off); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); try { mCaptureSession.setRepeatingRequest( mPreviewRequestBuilder.build(), mPreCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); return; } break; } }
在takePicture()之前,需要再次设置:
private void setFlashMode() { switch (mFlashMode) { case 0: mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); break; case 1: mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); break; case 2: mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); break; } }
代码参考:https://github.com/gengqifu/361Camera,欢迎fork/star。
推荐阅读
- Android permission 动态申请授权
- Android Camera2 拍照——对焦模式
- 大规模集群要求swappiness内核参数调优
- Android Camera2拍照——使用SurfaceView
- Android Camera2 拍照——使用TextureView
- if __name__ == "__main__": tf.app.run()
- mac下创建安卓应用hello-world
- Android Camera2 拍照入门学习
- app自动化测试中的相关api