一、切换摄像头
在前后摄像头之间切换,首先需要关闭之前打开的摄像头,关闭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。