Android camera2入门之一 —— 开启预览

Android API21新增了camera2,这与之前的camera架构完全不同,使用起来也比较复杂,但是功能变得很强大。

在讲解开启预览之前,首先需要了解camera2的几个比较重要的类

  • CameraManager: 管理手机上的所有摄像头设备,它的作用主要是选择前后摄像头和创建CameraDevice
  • CameraDevice: 具体的摄像头设备,它有一系列参数,可以通过CameraManager的getCameraCharacteristics()方法获取。它的作用主要是创建CameraCaptureSession以及创建CaptureRequest
  • CameraCaptureSession: 处理拍照和预览的工作(很重要)
  • CaptureRequest: 定义所有的拍照参数,比如图像处理的算法、输出缓冲区以及显示界面(TextureView或SurfaceView)等

下面开始讲解如何预览

1.定义一个TextureView,作为预览界面

    textureView = (TextureView) findViewById(R.id.textureView);
        assert textureView != null;
        textureView.setSurfaceTextureListener(textureListener);

       TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            //在此处打开摄像头
            openCamera();
        }
          ...
        };

2.开启子线程,可以在OnResume()方法方法中注册,在onPause()方法中停止

mBackgroundThread = new HandlerThread("Camera Background");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());

3.打开摄像头并获取CameraDevice

      private void openCamera() {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            cameraId = manager.getCameraIdList()[0];
            //指定相机的参数
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
            StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            assert map != null;
            //获取所支持尺寸中最大的那个
            imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
            // 检查权限
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
                return;
            }
            //打开摄像头,在stateCallback回调接口中获取CameraDevice
            manager.openCamera(cameraId, stateCallback, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice camera) {
            //当摄像头打开后回调此方法
            cameraDevice = camera;
            //开启相机预览
            createCameraPreview();
        }
 }

4.开启相机预览

protected void createCameraPreview() {
        try {
            SurfaceTexture texture = textureView.getSurfaceTexture();
            assert texture != null;
            //设置默认缓冲区的尺寸和相机所支持的最大尺寸一样
            texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
            //开启预览所需要的输出Surface
            Surface surface = new Surface(texture);
            //创建一个带有输出Surface的CaptureRequest.Builder
            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            captureRequestBuilder.addTarget(surface);
            //创建预览所需要的CameraCaptureSession
            cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){
                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    //若摄像头已关闭,则退出
                    if (null == cameraDevice) {
                        return;
                    }
                    // 当CameraCaptureSession已准备好,开启预览
                    cameraCaptureSessions = cameraCaptureSession;
                    //配置预览时使用3A模式(自动曝光、自动对焦、自动白平衡)
                    captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
        try {
             //最后显示相机预览界面,captureRequestBuilder.build()用于生成CaptureRequest
             cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

你可能感兴趣的:(android,预览,摄像头,camera2)