1. 相机使用流程
图1.jpg
2. SurfaceView
/**
* Android 5.0 使用Camera2 照相
* 使用SurfaceView显示
* 主要步骤:
* 1. 获得摄像头管理器CameraManager mCameraManager,mCameraManager.openCamera()来打开摄像头
* 2. 指定要打开的摄像头,并创建openCamera()所需要的CameraDevice.StateCallback stateCallback
* 3. 在CameraDevice.StateCallback stateCallback中调用takePreview(),这个方法中,使用CaptureRequest.Builder创建预览需要的CameraRequest,并初始化了CameraCaptureSession,最后调用了setRepeatingRequest(previewRequest, null, childHandler)进行了预览
* 4. 点击拍照按钮,调用takePicture(),这个方法内,最终调用了capture(mCaptureRequest, null, childHandler)
* 5. 在new ImageReader.OnImageAvailableListener(){}回调方法中,将拍照拿到的图片进行展示
*/
public class CameraSurfaceFragment extends Fragment {
/**照相机设备请求码*/
private static final int REQUEST_CAMERA_CODE = 0x100;
/**拍照*/
private Button mBtnTake;
/**显示拍照好的图片*/
private ImageView mIvShow;
/**预览窗口*/
private SurfaceView mSurfaceView;
/**预览窗口Holder*/
private SurfaceHolder mSurfaceHolder;
/**子线程Handler*/
private Handler mChildHandler;
/**主线程Handler*/
private Handler mMainHandler;
/**照相机ID,标识前置,后置*/
private String mCameraId;
/**图片读取器*/
private ImageReader mImageReader;
/**摄像头管理者*/
private CameraManager mCameraManager;
/**照相机设备*/
private CameraDevice mCameraDevice;
/**照相会话*/
private CameraCaptureSession mCameraCaptureSession;
/**方向列表*/
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
/**
* 摄像头状态监听
*/
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 打开摄像头
mCameraDevice = camera;
// 开启预览
takePreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
// 关闭摄像头
if (null != mCameraDevice) {
// 关闭摄像头
mCameraDevice.close();
mCameraDevice = null;
}
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
// 摄像头异常
Toast.makeText(getContext(), "摄像头开启失败", Toast.LENGTH_SHORT).show();
}
};
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_camera_surface, container, false);
initView(root);
initListener();
return root;
}
/**
* 初始化View
*/
private void initView(View view) {
// 绑定View
mIvShow = view.findViewById(R.id.iv_show);
mBtnTake = view.findViewById(R.id.btn_take);
mSurfaceView = view.findViewById(R.id.sv_camera);
// 获取Holder
mSurfaceHolder = mSurfaceView.getHolder();
// 设置屏幕常量
mSurfaceHolder.setKeepScreenOn(true);
// 设置SurfaceView回调
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
// SurfaceView 创建
initCamera();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// SurfaceView 改变
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// SurfaceView 销毁
// 销毁照相机设备
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
});
}
/**
* 初始化监听器
*/
private void initListener() {
mBtnTake.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
}
/**
* 初始化照相机
*/
private void initCamera() {
// 创建Handler线程并启动
HandlerThread handlerThread = new HandlerThread("Camera");
handlerThread.start();
// 创建子线程Handler
mChildHandler = new Handler(handlerThread.getLooper());
// 创建主线程Handler
mMainHandler = new Handler(Looper.getMainLooper());
// 设置后置摄像头ID
mCameraId = String.valueOf(CameraCharacteristics.LENS_FACING_FRONT);
// 创建图片读取器
mImageReader = ImageReader.newInstance(1080, 1920, ImageFormat.JPEG, 1);
// 图片读取器设置图片可用监听
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
showImage(reader);
}
}, mMainHandler);
// 获取摄像头管理
mCameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
// 打开摄像头
try {
if (ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// 申请权限
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_CODE);
} else {
// 打开摄像头
mCameraManager.openCamera(mCameraId, mStateCallback, mMainHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (REQUEST_CAMERA_CODE == requestCode) {
// 权限允许
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager.openCamera(mCameraId, mStateCallback, mMainHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
} else {
// 权限拒绝
Toast.makeText(getContext(), "无权限", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 图片可用后,读取并显示图片
* @param reader 图片读取器
*/
private void showImage(ImageReader reader) {
// 拿到图片数据
Image image = reader.acquireNextImage();
// 获取字节缓冲
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
// 创建与缓冲区相同的字节数组
byte[] bytes = new byte[buffer.remaining()];
// 将数据读取字节数组
buffer.get(bytes);
// 创建图片
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
// 显示图片
if (null != bitmap) {
mIvShow.setImageBitmap(bitmap);
}
}
/**
* 预览
*/
private void takePreview() {
try {
// 创建预览需要的CaptureRequest.Builder
final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将SurfaceView的surface作为Builder的目标
builder.addTarget(mSurfaceHolder.getSurface());
// 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
// 检测设备是否为空
if (null == mCameraDevice) return;
// 配置
// 当摄像头已经准备好时,开始显示预览
mCameraCaptureSession = session;
try {
// 自动对焦
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 打开闪光灯
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 显示预览
CaptureRequest request = builder.build();
// 会话设置重复请求
mCameraCaptureSession.setRepeatingRequest(request, null, mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Toast.makeText(getContext(), "配置失败", Toast.LENGTH_SHORT).show();
}
}, mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 拍照
*/
private void takePicture() {
// 判断设备是否为空
if (null == mCameraDevice) return;
// 创建拍照需要的CaptureRequest.Builder
final CaptureRequest.Builder builder;
try {
// 创建拍照请求
builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// 将imageReader的surface作为CaptureRequest.Builder的木白哦
builder.addTarget(mImageReader.getSurface());
// 自动对焦
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 自动曝光
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 获取手机方向
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
// 根据设备方向计算设置照片的方向
builder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
// 拍照
CaptureRequest request = builder.build();
// 拍照会话执行拍照
mCameraCaptureSession.capture(request, null, mChildHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
3. TextureView
/**
* Camera2 与 Texture使用
*/
public class CameraTextureFragment extends Fragment {
/**相机权限请求标识*/
private static final int REQUEST_CAMERA_CODE = 0x100;
/**预览*/
private TextureView mTextureView;
/**拍照按钮*/
private Button mBtnTake;
/**图片*/
private ImageView mImageView;
/**照相机ID,标识前置后置*/
private String mCameraId;
/**相机尺寸*/
private Size mCaptureSize;
/**图像读取者*/
private ImageReader mImageReader;
/**图像主线程Handler*/
private Handler mCameraHandler;
/**相机设备*/
private CameraDevice mCameraDevice;
/**预览大小*/
private Size mPreviewSize;
/**相机请求*/
private CaptureRequest.Builder mCameraCaptureBuilder;
/**相机拍照捕获会话*/
private CameraCaptureSession mCameraCaptureSession;
/**相机管理者*/
private CameraManager mCameraManager;
/**相机设备状态回调*/
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 打开
mCameraDevice = camera;
// 开始预览
takePreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
// 断开连接
camera.close();
mCameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
// 异常
camera.close();
mCameraDevice = null;
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_camera_texture, container, false);
initView(root);
initListener();
return root;
}
/**
* 初始化View
*/
private void initView(View view) {
// 初始化View
mImageView = view.findViewById(R.id.iv_show);
mTextureView = view.findViewById(R.id.tv_camera);
mBtnTake = view.findViewById(R.id.btn_take);
}
@Override
public void onResume() {
super.onResume();
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
// SurfaceTexture可用
// 设置相机参数并打开相机
setUpCamera(width, height);
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// SurfaceTexture大小改变
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
// SurfaceTexture 销毁
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// SurfaceTexture 更新
}
});
}
/**
* 打开相机
*/
private void openCamera() {
// 获取照相机管理者
mCameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
try {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_CODE);
return;
}
// 打开相机
mCameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (REQUEST_CAMERA_CODE == requestCode) {
// 权限允许
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
} else {
// 权限拒绝
Toast.makeText(getContext(), "无权限", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 设置相机参数
* @param width 宽度
* @param height 高度
*/
private void setUpCamera(int width, int height) {
// 创建Handler
mCameraHandler = new Handler(Looper.getMainLooper());
// 获取摄像头的管理者
CameraManager cameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
try {
// 遍历所有摄像头
for (String cameraId : cameraManager.getCameraIdList()) {
// 相机特性
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
// 获取摄像头是前置还是后置
Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
// 此处默认打开后置摄像头
if (null != facing && CameraCharacteristics.LENS_FACING_FRONT == facing) continue;
// 获取StreamConfigurationMap,管理摄像头支持的所有输出格式和尺寸
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
// 根据TextureView的尺寸设置预览尺寸
mPreviewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);
// 获取相机支持的最大拍照尺寸
mCaptureSize = Collections.max(
Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new Comparator<Size>() {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getHeight() * rhs.getWidth());
}
});
// 此处ImageReader用于拍照所需
setupImageReader();
// 为摄像头赋值
mCameraId = cameraId;
break;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 设置ImageReader
*/
private void setupImageReader() {
// 2代表ImageReader中最多可以获取两帧图像流
mImageReader = ImageReader.newInstance(mCaptureSize.getWidth(), mCaptureSize.getHeight(), ImageFormat.JPEG, 1);
// 设置图像可用监听
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
// 获取图片
final Image image = reader.acquireNextImage();
// 提交任务,保存图片
mCameraHandler.post(new ImageSaver(image));
// 更新UI
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// 获取字节缓冲区
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
// 创建数组之前调用此方法,恢复默认设置
buffer.rewind();
// 创建与缓冲区内容大小相同的数组
byte[] bytes = new byte[buffer.remaining()];
// 从缓冲区存入字节数组,读取完成之后position在末尾
buffer.get(bytes);
// 获取Bitmap图像
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
// 显示
if (null != bitmap) {
mImageView.setImageBitmap(bitmap);
}
}
});
}
}, mCameraHandler);
}
/**
* 选择SizeMap中大于并且最接近width和height的size
* @param sizeMap 可选的尺寸
* @param width 宽
* @param height 高
* @return 最接近width和height的size
*/
private Size getOptimalSize(Size[] sizeMap, int width, int height) {
// 创建列表
List<Size> sizeList = new ArrayList<>();
// 遍历
for (Size option : sizeMap) {
// 判断宽度是否大于高度
if (width > height) {
if (option.getWidth() > width && option.getHeight() > height) {
sizeList.add(option);
}
} else {
if (option.getWidth() > height && option.getHeight() > width) {
sizeList.add(option);
}
}
}
// 判断存储Size的列表是否有数据
if (sizeList.size() > 0) {
return Collections.min(sizeList, new Comparator<Size>() {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getWidth() * rhs.getHeight());
}
});
}
return sizeMap[0];
}
/**
* 设置监听
*/
private void initListener() {
mBtnTake.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
}
/**
* 预览
*/
private void takePreview(){
// 获取SurfaceTexture
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
// 设置默认的缓冲大小
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// 创建Surface
Surface previewSurface = new Surface(surfaceTexture);
try {
// 创建预览请求
mCameraCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将previewSurface添加到预览请求中
mCameraCaptureBuilder.addTarget(previewSurface);
// 创建会话
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
// 配置
CaptureRequest captureRequest = mCameraCaptureBuilder.build();
// 設置session
mCameraCaptureSession = session;
// 设置重复预览请求
mCameraCaptureSession.setRepeatingRequest(captureRequest, null, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
// 配置失败
}
}, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 拍照
*/
private void takePicture() {
try {
// 设置触发
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
mCameraCaptureBuilder.addTarget(mImageReader.getSurface());
// 拍照
mCameraCaptureSession.capture(mCameraCaptureBuilder.build(), null, mCameraHandler);
} catch (CameraAccessException e) {
Toast.makeText(getActivity(), "异常", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
/**
* 保存图片任务
*/
private class ImageSaver implements Runnable {
/**图像*/
private Image mImage;
ImageSaver(Image image) {
this.mImage = image;
}
@Override
public void run() {
// 获取字节缓冲区
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
// 创建数组之前调用此方法,恢复默认设置--重要
buffer.rewind();
// 创建与字节缓冲区大小相同的字节数组
byte[] data = new byte[buffer.remaining()];
// 将数据读取字节数组
buffer.get(data);
// 获取缓存路径
String path = getActivity().getExternalCacheDir().getPath();
// 获取时间戳
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
// 文件名
String fileName = path + "/IMG_" + timeStamp + ".jpg";
// 创建文件输出流
FileOutputStream fos = null;
try {
// 初始化文件输出流
fos = new FileOutputStream(fileName);
// 将数据写入文件
fos.write(data, 0, data.length);
// 刷新缓冲区
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fos) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
4. 多功能相机
/**
* 后置摄像头
*/
private static final int CAMERA_FRONT = CameraCharacteristics.LENS_FACING_FRONT;
/**
* 前置摄像头
*/
private static final int CAMERA_BACK = CameraCharacteristics.LENS_FACING_BACK;
/**
* 照相机ID,标识前置后置
*/
private String mCameraId;
/**
* 切换前后摄像头
*/
private void switchCamera() {
if (String.valueOf(CAMERA_FRONT).equals(mCameraId)) {
// 后置
mCameraId = String.valueOf(CAMERA_BACK);
} else if (String.valueOf(CAMERA_BACK).equals(mCameraId)) {
// 前置
mCameraId = String.valueOf(CAMERA_FRONT);
}
closeCamera();
reOpenCamera();
}
/**
* 重新打开摄像头
*/
private void reOpenCamera() {
if (mTextureView.isAvailable()) {
openCamera();
} else {
setTextureListener();
}
}
/**
* 关闭摄像头
*/
private void closeCamera() {
if (null != mCameraCaptureSession) {
mCameraCaptureSession.close();
mCameraCaptureSession = null;
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
if (null != mImageReader) {
mImageReader.close();
mImageReader = null;
}
}
/**
* 无延时
*/
private static final int DELAY_ZERO = 0;
/**
* 延时3秒
*/
private static final int DELAY_THREE = 3;
/**
* 延时10秒
*/
private static final int DELAY_TEN = 10;
/**
* 延时拍摄
*/
private void delayTake() {
switch (mDelayTime) {
case DELAY_ZERO:
mDelayTime = DELAY_THREE;
break;
case DELAY_THREE:
mDelayTime = DELAY_TEN;
break;
case DELAY_TEN:
mDelayTime = DELAY_ZERO;
break;
}
mBtnDelay.setText("延时" + mDelayTime + "秒");
if (mDelayTime == DELAY_ZERO) {
takePicture();
} else {
// 定时器
new CountDownTimer(mDelayTime * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
mBtnDelay.setText(String.valueOf(millisUntilFinished/1000) + "秒");
}
@Override
public void onFinish() {
mBtnDelay.setText("延时" + mDelayTime + "秒");
takePicture();
}
}.start();
}
}
/**
* 闪光标识--自动开启
*/
private static final int FLASH_ZERO = 0;
/**
* 闪光标识--总是开启
*/
private static final int FLASH_ONE = 1;
/**
* 闪光标识--关闭
*/
private static final int FLASH_TWO = 2;
/**
* 切换闪光模式
*/
private void switchFlash() {
switch(mFlashMode) {
case FLASH_ZERO:
mFlashMode = FLASH_ONE;
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
break;
case FLASH_ONE:
mFlashMode = FLASH_TWO;
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
break;
case FLASH_TWO:
mFlashMode = FLASH_ZERO;
mCameraCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
// 必须设置
mCameraCaptureBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
break;
}
try {
mCameraCaptureSession.setRepeatingRequest(mCameraCaptureBuilder.build(), null, mCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
网友评论