Android Camera2使用

作者: _凌浩雨 | 来源:发表于2018-06-25 12:50 被阅读12次

    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();
        }
      }
      
    

    代码下载

    相关文章

      网友评论

        本文标题:Android Camera2使用

        本文链接:https://www.haomeiwen.com/subject/znxyyftx.html