camera2 预览拍照流程及其预览拍照镜像处理方法

private CaptureRequest.Builder mPreviewBuilder; // 声明一个预览请求构建器对象
private CaptureRequest.Builder mCaptureBuilder; // 声明一个拍照请求构建器对象

一、打开相机
// 从系统服务中获取相机管理器
CameraManager cm = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
// 获取可用相机特性
CameraCharacteristics cc = cm.getCameraCharacteristics(cameraId);
CameraDevice.StateCallback mDeviceStateCallback = new CameraDevice.StateCallback()
// 开启摄像头,在StateCallback 回调onOpened 之后,初始化CameraDevice mCameraDevice并 开启预览,
cm.openCamera(cameraId, mDeviceStateCallback, mHandler);

二、开启预览
// 获取纹理视图的表面纹理
SurfaceTexture texture = mPlayerView.getSurfaceTexture();
// 设置表面纹理的默认缓存尺寸:即预览尺寸
texture.setDefaultBufferSize(mPreViewSize.getWidth(), mPreViewSize.getHeight());
// 创建一个该表面纹理的表面对象
mSurface = new Surface(texture);
//创建预览请求构建器对象,通过该对象可以设置曝光、对焦、预览方向等
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

//创建ImageReader,并设置拍照数据监听
mImageReader = ImageReader.newInstance(Config.SHOOT_PIC_WIDTH,
Config.SHOOT_PIC_HEIGHT, ImageFormat.JPEG, 1);
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
//获取最新的image
Image image = reader.acquireLatestImage();
//用完后面一定要调用close,否则crash 且不会有持续的预览回调,
image.close();
}, null);
// 把纹理视图添加到预览目标,不添加没法预览
mPreviewBuilder.addTarget(mSurface);
//添加这句可以获取实时预览数据回调,一般ImageReader 设置格式为ImageFormat.YUV_420_888 处理实时yuv预览帧
//比如做算法处理等
mPreviewBuilder.addTarget(mImageReader.getSurface());

// 创建一个相片捕获会话。此时需要两个surface(texureview和ImageReader)该对象负责管理处理预览请求和拍照请求
mCameraDevice.createCaptureSession(Arrays.asList(mSurface, mImageReader.getSurface()),
mSessionStateCallback, mHandler);
//在CameraCaptureSession 配置成功回调后调用
CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback(){
@Override
public void onConfigured(CameraCaptureSession session) {
mCameraSession = session;
// 设置连拍请求。此时预览画面
mCameraSession.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
}
}

三、拍照
//创建拍照请求构建器对象,该对象需要设置ImageReader的surface对象,设置图片方向等
mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
mCaptureBuilder.addTarget(mImageReader.getSurface());

//执行拍照,CaptureCallback只是处理拍照状态回调,拍照数据从上面的ImageReader回调获取
//如果拍照的时候是停止预览的,再拍照回调完成后需要在调用mCameraSession.setRepeatingRequest
mCameraSession.capture(mCaptureBuilder.build(), mCaptureCallback, mHandler);
CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession
.CaptureCallback()
四、其他 预览拍照做镜像处理
现在cameraid只有是前摄才会做镜像处理,但是车机中舱内摄像头 cameraid 不是前摄的,
但是也要做前摄的预览拍照效果,该怎么办
1.预览界面做镜像
//如果需要将预览界面镜像处理,可以对texture view做处理 镜像翻转处理。
ArchTaskExecutor.getInstance().executeOnMainThread(() -> {
mPlayerView.setScaleX(-1f);
});
2.imagereader 拍照 做镜像处理
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
//处理拍照回调,保存拍照数据
Bitmap bitmap = getByteFromReader(reader);
Log.i(TAG, "onImageAvailable() null != bitmap?" + (null != bitmap));
Bitmap bitmap2 = flipBitmap(bitmap);
if (null != bitmap2) {
doCaptureAfterGetImage(bitmap2);
}
}
}, null);

/**
* 对图片做镜像处理
*
* @param bitmap
*/
private Bitmap flipBitmap(Bitmap bitmap) {
if (null == bitmap) {
return null;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix m = new Matrix();
m.postScale(-1, 1); //镜像水平翻转
//m.postScale(1, -1); //镜像垂直翻转
//m.postRotate(-90); //旋转-90度
Bitmap new2 = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, true);
bitmap.recycle();
return new2;
}

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值