android camera2自定义,Android自定义Camera2 拍照,用SurfaceView预览。

这篇博客详细介绍了如何使用Android的Camera2 API来实现自定义相机的预览和拍照功能。从创建CameraManager,到设置SurfaceView,再到建立CameraCaptureSession,每一步都清晰地展示了代码实现。同时,还提供了开启和关闭闪光灯的方法。整个过程涉及异步处理、权限检查和图像处理等关键步骤,为开发者提供了一个完整的自定义相机实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

布局文件不用说了,就它了SurfaceView。其他花里古哨的布局,自己想着加吧!

surfaceView的findViewById()的事就不说了,直接开始预览的代码

//6.0开始

private CameraManager manager;

private Handler childHandler, mainHandler;

private CameraDevice mCamera;

private CaptureRequest.Builder mPreviewBuilder;

private CameraCaptureSession mSession;

private ImageReader mImageReader;

// 创建拍照需要的CaptureRequest.Builder

private CaptureRequest.Builder captureRequestBuilder;

//6.0结束

//很多过程都变成了异步的了,所以这里需要一个子线程的looper

HandlerThread handlerThread = new HandlerThread("Camera2");

handlerThread.start();

childHandler = new Handler(handlerThread.getLooper());

mainHandler = new Handler(getMainLooper());

manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

holder = surfaceView.getHolder();

holder.setKeepScreenOn(true);

holder.addCallback(new SurfaceHolder.Callback() {

@Override

public void surfaceCreated(SurfaceHolder surfaceHolder) {

try {

//需要相机权限

if (ActivityCompat.checkSelfPermission(getPageContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

return;

}

//获取可用相机设备列表

String[] CameraIdList = manager.getCameraIdList();

//打开相机

manager.openCamera(CameraIdList[0], mCameraDeviceStateCallback, mainHandler);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

@Override

public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

}

@Override

public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

//释放资源

if (mCamera != null) {

mCamera.close();

mCamera = null;

}

}

});

//设置照片的大小

mImageReader = ImageReader.newInstance(3264, 1840, ImageFormat.JPEG, 2);

mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {

@Override

public void onImageAvailable(ImageReader imageReader) {

// 拿到拍照照片数据

Image image = imageReader.acquireNextImage();

ByteBuffer buffer = image.getPlanes()[0].getBuffer();

byte[] bytes = new byte[buffer.remaining()];

buffer.get(bytes);//由缓冲区存入字节数组

image.close();

//saveBitmap(bytes);//保存照片的处理

}

}, mainHandler);

/**

* 摄像头创建监听

*/

private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {

@Override

public void onOpened(CameraDevice camera) {//打开摄像头

try {

//开启预览

mCamera = camera;

startPreview(camera);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

@Override

public void onDisconnected(CameraDevice camera) {

//关闭摄像头

if (mCamera != null) {

mCamera.close();

mCamera = null;

}

}

@Override

public void onError(CameraDevice camera, int error) {

//发生错误

}

};

//开始预览,主要是camera.createCaptureSession这段代码很重要,创建会话

private void startPreview(final CameraDevice camera) throws CameraAccessException {

try {

// 创建预览需要的CaptureRequest.Builder

mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

// 将SurfaceView的surface作为CaptureRequest.Builder的目标

mPreviewBuilder.addTarget(holder.getSurface());

mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);

mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);

//设置拍摄图像时相机设备是否使用光学防抖(OIS)。

mPreviewBuilder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON);

//感光灵敏度

mPreviewBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, 1600);

//曝光补偿//

mPreviewBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);

// 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求

camera.createCaptureSession(Arrays.asList(holder.getSurface(), mImageReader.getSurface()), mSessionStateCallback, childHandler);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

/**

* 会话状态回调

*/

private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {

@Override

public void onConfigured(CameraCaptureSession session) {

mSession = session;

if (mCamera != null && captureRequestBuilder == null) {

try {

captureRequestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);

// 将imageReader的surface作为CaptureRequest.Builder的目标

captureRequestBuilder.addTarget(mImageReader.getSurface());

//关闭自动对焦

captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);

captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);

//设置拍摄图像时相机设备是否使用光学防抖(OIS)。

captureRequestBuilder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_ON);

captureRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, valueISO);

//曝光补偿//

captureRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

try {

updatePreview(session);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

@Override

public void onConfigureFailed(CameraCaptureSession session) {

}

};

/**

* 更新会话,开启预览

*

* @param session

* @throws CameraAccessException

*/

private void updatePreview(CameraCaptureSession session) throws CameraAccessException {

session.setRepeatingRequest(mPreviewBuilder.build(), mCaptureCallback, childHandler);

}

private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() {

@Override

public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {

super.onCaptureCompleted(session, request, result);

//需要连拍时,循环保存图片就可以了

}

};

预览已经OK了。简单至极吧。

下面是一个camera拍照的方法:

/**

* 单拍照片

*/

private void takePicture() {

if (mCamera == null) {

return;

}

if (mSession != null && captureRequestBuilder != null) {

//拍照

try {

CaptureRequest cr = captureRequestBuilder.build();

mSession.capture(cr, null, null);//单拍API,也可以调连拍的哦

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

}

OK拍照也可以了,再来就是单独控制闪光灯的开启和关闭了

/**

* 6.0开

*/

public void openLight6() {

try {

mPreviewBuilder.set(CaptureRequest.FLASH_MODE,

CaptureRequest.FLASH_MODE_TORCH);

updatePreview(mSession);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

/**

* 6.0关

*/

public void closeLight6() {

try {

mPreviewBuilder.set(CaptureRequest.FLASH_MODE,

CaptureRequest.FLASH_MODE_OFF);

updatePreview(mSession);

} catch (CameraAccessException e) {

e.printStackTrace();

}

}

OK,自定义camera2 拍照预览就完成了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值