您当前的位置: 首页 >  android

Kevin-Dev

暂无认证

  • 4浏览

    0关注

    544博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android -- 相机】Camera1 实现拍照 & 预览功能

Kevin-Dev 发布时间:2020-05-07 22:04:30 ,浏览量:4

前言

Camera1 在 API 21 的时候已经被弃用了,虽然现在google 都推荐 使用 Camerax 来实现相机的一些功能,但这不妨碍我们学习 Camera1 和 Camera2,对此有基础了解,为后续学习 Camera2 和 Camerax 做铺垫

本篇文章,你将学习到:

  1. 实现相机的开启与预览
  2. 调整预览方向
  3. 切换摄像头
  4. 拍照及调整图片方向
一、实现相机的开启与预览

1. 效果图 在这里插入图片描述

2. 在清单文件中申请权限

	
    
    

3. 在 Java 代码中添加运行时权限授权,在 Activity 的 onCreate 函数中添加如下代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[] {Manifest.permission.CAMERA}, 1);
            }
        }

4. 布局文件




    

    

        

        
        

    

5. 获取相机个数 一般手机中,都有前置摄像头和后置摄像头,我们可以根据 Camera 的 getNumberOfCameras() 方法,来获取这些信息。比如:

	/**
     * 初始化相机
     */
    private void initCamera() {
        //获取相机个数
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i  height 的,而我们的UI是3:4,所以这里也要做换算
     *
     * @param shortSize
     * @param longSize
     */
    private void initPreviewParams(int shortSize, int longSize) {
        Camera camera = mCamera;
        if (camera != null) {
            Camera.Parameters parameters = camera.getParameters();
            //获取手机支持的尺寸
            List sizes = parameters.getSupportedPreviewSizes();
            Camera.Size bestSize = getBestSize(shortSize, longSize, sizes);
            //设置预览大小
            parameters.setPreviewSize(bestSize.width, bestSize.height);
            //设置图片大小,拍照
            parameters.setPictureSize(bestSize.width, bestSize.height);
            //设置格式
            parameters.setPreviewFormat(ImageFormat.NV21);

            //设置自动聚焦
            List modes = parameters.getSupportedFocusModes();
            //查看支持的聚焦模式
            for (String mode : modes) {
                //默认图片聚焦模式
                if (mode.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                    break;
                }
            }
            camera.setParameters(parameters);
        }
    }

8. 相机预览大小 首先,应该根据自己UI的大小去设置相机预览的大小,如果你的控件为 200x200,但相机的数据为 1920x1080 ,这样填充过去,画面肯定是会被拉伸的。

List sizes = parameters.getSupportedPreviewSizes()

注意相机的 width > height,所以获取一个最佳的预览尺寸可以这样写:

/**
     * 获取预览最后尺寸
     *
     * @param shortSize
     * @param longSize
     * @param sizes
     * @return
     */
    private Camera.Size getBestSize(int shortSize, int longSize, List sizes) {
        Camera.Size bestSize = null;
        float uiRatio = (float) longSize / shortSize;
        float minRatio = uiRatio;
        for (Camera.Size previewSize : sizes) {
            float cameraRatio = (float) previewSize.width / previewSize.height;

            //如果找不到比例相同的,找一个最近的,防止预览变形
            float offset = Math.abs(cameraRatio - minRatio);
            if (offset = Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[] {Manifest.permission.CAMERA}, 1);
            }
        }

        initCamera();

        //打开摄像头
        openCamera(mBackCameraId);
    }

    /**
     * 初始化相机
     */
    private void initCamera() {
        //获取相机个数
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i  height 的,而我们的UI是3:4,所以这里也要做换算
     *
     * @param shortSize
     * @param longSize
     */
    private void initPreviewParams(int shortSize, int longSize) {
        Camera camera = mCamera;
        if (camera != null) {
            Camera.Parameters parameters = camera.getParameters();
            //获取手机支持的尺寸
            List sizes = parameters.getSupportedPreviewSizes();
            Camera.Size bestSize = getBestSize(shortSize, longSize, sizes);
            //设置预览大小
            parameters.setPreviewSize(bestSize.width, bestSize.height);
            //设置图片大小,拍照
            parameters.setPictureSize(bestSize.width, bestSize.height);
            //设置格式
            parameters.setPreviewFormat(ImageFormat.NV21);

            //设置自动聚焦
            List modes = parameters.getSupportedFocusModes();
            //查看支持的聚焦模式
            for (String mode : modes) {
                //默认图片聚焦模式
                if (mode.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                    break;
                }
            }
            camera.setParameters(parameters);
        }
    }

    /**
     * 获取预览最后尺寸
     *
     * @param shortSize
     * @param longSize
     * @param sizes
     * @return
     */
    private Camera.Size getBestSize(int shortSize, int longSize, List sizes) {
        Camera.Size bestSize = null;
        float uiRatio = (float) longSize / shortSize;
        float minRatio = uiRatio;
        for (Camera.Size previewSize : sizes) {
            float cameraRatio = (float) previewSize.width / previewSize.height;

            //如果找不到比例相同的,找一个最近的,防止预览变形
            float offset = Math.abs(cameraRatio - minRatio);
            if (offset             
关注
打赏
1658837700
查看更多评论
0.1343s