Android Camera2 相机预览、获取数据

Camera2简要说明

在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2),大幅提高了Android系统拍照的功能,还能支持RAW照片输出,允许程序调整相机的对焦模式、曝光模式、快门等

源码地址

https://github.com/WuKaik/QuickCamera.git

需要了解camera2的几个重要类

  • CameraManager: 管理设备上的所有摄像头设备,主要是获取摄像头列表和打开指定的摄像头
  • CameraCharacteristics:摄像头特性,该对象通过CameraManager来获取,用于描述特定摄像头所支持的各种特性
  • CameraDevice: 具体的摄像头设备,主要是创建CaptureSession和CaptureRequest
  • CameraCaptureSession: 相机捕获会话,主要是处理拍照和预览,需要预览、拍照时,都需要先通过该类的实例创建          Session
  • CaptureRequest.Builder:负责生成CameraRequest对象
  • CaptureRequest: 通过CaptureRequest.Builder.build()后得到的一次捕获请求,用于描述捕获图片的各种参数设置,比如对焦模式、曝光模式……

使用简要说明

  • 获取CameraManager
  • 调用CameraManager.getCameraCharacteristics()方法得到CameraCharacteristics
  • 调用CameraManager.open()方法在回调中得到CameraDevice
  • 通过CameraDevice.createCaptureRequest()得到CaptureRequest.Builder,构建CaptureRequest对象
  • 通过CameraDevice.createCaptureSession() 在回调中获取CameraCaptureSession
  • 通过 CameraCaptureSession发送CaptureRequest, capture表示只发一次请求, setRepeatingRequest表示不断发送请求.
  • 在ImageReader.OnImageAvailableListener回调中获取拍照数据

主要代码截图

/**
     * 开始预览
     * 使用TextureView显示相机预览数据
     * Camera2的预览和拍照数据都是使用CameraCaptureSession会话来请求的
     */
    private void startPreview() {
        SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
        //设置TextureView缓冲区大小
        surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        //获取Surface显示数据
        Surface surface = new Surface(surfaceTexture);
        try {
            //设置捕获请求为预览(还有其它,如拍照、录像)
            mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            //可以通过这个set(key,value)方法,设置曝光啊,自动聚焦等参数!!
            //mCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            //获取ImageReader(ImageFormat不要使用jpeg,预览会出现卡顿)
            mReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.YUV_420_888, 2);
            //设置有图像数据流时监听
            mReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader) {
                    //需要调用acquireLatestImage()和close(),不然会卡顿
                    Image image = reader.acquireLatestImage();
                    //将这帧数据转成字节数组,类似于Camera1的PreviewCallback回调的预览帧数据
                    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                    byte[] data = new byte[buffer.remaining()];
                    buffer.get(data);
                    //Log.d(TAG, "onImageAvailable: data size"+data.length);
                    image.close();
                }
            }, mHandler);
            //设置预览界面为数据的显示
            mCaptureBuilder.addTarget(surface);
            mCaptureBuilder.addTarget(mReader.getSurface());
            //创建相机捕获会话
            mCameraDevice.createCaptureSession(Arrays.asList(surface, mReader.getSurface()), mCaptureStateCallback, mHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

 

 private CameraCaptureSession.StateCallback mCaptureStateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            //创建捕获请求
            mCaptureRequest = mCaptureBuilder.build();
            mCameraSession = session;
            try {
                //设置反复捕获数据的请求,这样预览界面就会一直有数据显示
                mCameraSession.setRepeatingRequest(mCaptureRequest, null, mHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {

        }
    };

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值