前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android RTMP】Android Camera 视频数据采集预览 ( 图像传感器方向设置 | Camera 使用流程 | 动态权限申请 )

【Android RTMP】Android Camera 视频数据采集预览 ( 图像传感器方向设置 | Camera 使用流程 | 动态权限申请 )

作者头像
韩曙亮
发布2023-03-27 21:23:43
1.8K0
发布2023-03-27 21:23:43
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、 Camera 传感器方向简介


1 . Camera 采集 NV21 图像数据 : 手机 Camera 采集的图像数据完毕后 , 通过 PreviewCallback 接口的 onPreviewFrame 回调方法获取 NV21 图像数据 ;

2 . NV21 图像数据来源 : 该数据的最底层来源是手机 Camera 硬件的图像传感器 ;

3 . 图像传感器采集图像机制 :

① 图像传感器坐标原点 : 图像传感器取景时有一个坐标原点 , 就是手机的右上角 ;

② 图像传感器坐标方向 : 从图像传感器原点 / 手机右上角 ( 0 , 0 ) 向右下角方向是 X 增加方向 , 从图像传感器原点 / 手机右上角 ( 0 , 0 ) 向左上角方向是 Y 增加方向 ;

在这里插入图片描述
在这里插入图片描述

二、 Camera 图像传感器横向显示数据


1 . 向左横向 : 当手机向左横放时 , 图像传感器原点及方向 , 屏幕的原点及方向如下 ;

① 传感器原点和方向 : 图像传感器 ( 手机右上角 ) 原点

( 0 , 0 )

, 向右 X 增加 , 向下 Y 增加 ;

② 屏幕原点和方向 : 手机屏幕当前左上角 ( 手机的右上角 ) 是屏幕原点 , 向右 X 增加 , 向下 Y 增加 ;

在这里插入图片描述
在这里插入图片描述

2 . 图像显示 : 屏幕传感器的方向与屏幕方向一致 , 此时没有显示图像传感器 : 横向界面的 Camera 采集的图像数据是正常的 ;

在这里插入图片描述
在这里插入图片描述

注意 : 这是向左横向显示的数据 , 如果向右横向 , 数据整个都倒过来了 ;

三、 Camera 图像传感器纵向显示数据


1 . 正常竖屏 : 此时还是以右上角为原点 , 采集横向图像 ,

① 传感器原点和方向 : 图像传感器 ( 手机右上角 ) 原点

( 0 , 0 )

, 向右 X 增加 , 向下 Y 增加 ;

② 屏幕原点和方向 : 手机屏幕当前左上角 ( 手机的右上角 ) 是屏幕原点 , 向右 X 增加 , 向下 Y 增加 ;

在这里插入图片描述
在这里插入图片描述

2 . 图像显示 : 屏幕传感器的方向与屏幕方向不一致 , 此时没有显示图像传感器 , 纵向数据是不正常的 , 此时垂直方向显示界面时 , 显示的拍照信息还是横向的 , 只是 Camera 采集的图像逆时针旋转了 90 度 ;

在这里插入图片描述
在这里插入图片描述

注意 : 这是向上纵向显示的数据 , 如果向下纵向 , 数据整个都倒过来了 ;

四、 设置 Camera 预览数据方向


1 . 纠正图像预览方向 : Google 官方提供了设置 Camera 预览方向的方式 , 以下代码定义在 Camera#setDisplayOrientation 文档注释中 , 为 Camera 设置了以下参数后 , 就不会有上述预览图像错误的问题产生 ;

2 . NV21 数据方向 : NV21 格式的图像数据的的实际方向还是错误的方向 , 需要用户自己使用时纠正 ;

代码语言:javascript
复制
    /**
     * 设置 Camera 预览方向
     * 如果不设置, 视频是颠倒的
     * 该方法内容拷贝自 {@link Camera#setDisplayOrientation} 注释, 这是 Google Docs 提供的
     * @param parameters
     */
    private void setCameraPreviewOrientation(Camera.Parameters parameters) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(mCameraFacing, info);
        mRotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (mRotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }
        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror
        } else { // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        mCamera.setDisplayOrientation(result);
    }

五、 Camera 使用流程


1 . 开启 Camera 摄像头 :

代码语言:javascript
复制
    /**
     * 开启 Camera 摄像头
     */
    private void startCameraNV21DataPreview() {
        try {
            Log.i("octopus", "startCameraNV21DataPreview");
            // 1. 打开指定方向的 Camera 摄像头
            mCamera = Camera.open(mCameraFacing);
            // 2. 获取 Camera 摄像头参数, 之后需要修改配置该参数
            Camera.Parameters parameters = mCamera.getParameters();
            // 3. 设置 Camera 采集后预览图像的数据格式 ImageFormat.NV21
            parameters.setPreviewFormat(ImageFormat.NV21);
            // 4. 设置摄像头预览尺寸
            setPreviewSize(parameters);
            // 5. 设置图像传感器参数
            setCameraPreviewOrientation(parameters);
            mCamera.setParameters(parameters);
            // 6. 计算出 NV21 格式图像 mWidth * mHeight 像素数据大小
            mNv21DataBuffer = new byte[mWidth * mHeight * 3 / 2];
            // 7. 设置 Camera 预览数据缓存区
            mCamera.addCallbackBuffer(mNv21DataBuffer);
            // 8. 设置 Camera 数据采集回调函数, 采集完数据后
            //    就会回调此 PreviewCallback 接口的
            //    void onPreviewFrame(byte[] data, Camera camera) 方法
            mCamera.setPreviewCallbackWithBuffer(this);
            // 9. 设置预览图像画面的 SurfaceView 画布
            mCamera.setPreviewDisplay(mSurfaceHolder);

            // 11. 开始预览
            mCamera.startPreview();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

2 . 释放 Camera 摄像头 :

代码语言:javascript
复制
    /**
     * 释放 Camera 摄像头
     */
    private void stopCameraNV21DataPreview() {
        if (mCamera != null) {
            // 下面的 API 都是 Android 提供的
            
            // 1. 设置预览回调接口, 这里设置 null 即可
            mCamera.setPreviewCallback(null);
            // 2. 停止图像数据预览
            mCamera.stopPreview();
            // 3. 释放 Camera
            mCamera.release();
            mCamera = null;
        }
    }

六、 Camera 动态权限申请


1 . Android 6.0 以下静态设置权限 : AndroidManifest.xml 设置静态权限 ;

代码语言:javascript
复制
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

2 . Android 6.0 以上动态获取权限 :

代码语言:javascript
复制
    /**
     * 需要获取的权限列表
     */
    private String[] permissions = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.INTERNET,
            Manifest.permission.MODIFY_AUDIO_SETTINGS,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.CAMERA
    };

    /**
     * 动态申请权限的请求码
     */
    private static final int PERMISSION_REQUEST_CODE = 888;

    /**
     * 动态申请权限
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void initPermissions() {
        if (isLacksPermission()) {
            //动态申请权限 , 第二参数是请求吗
            requestPermissions(permissions, PERMISSION_REQUEST_CODE);
        }
    }

    /**
     * 判断是否有 permissions 中的权限
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public boolean isLacksPermission() {
        for (String permission : permissions) {
            if(checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED){
                return true;
            }
        }
        return false;
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、 Camera 传感器方向简介
  • 二、 Camera 图像传感器横向显示数据
  • 三、 Camera 图像传感器纵向显示数据
  • 四、 设置 Camera 预览数据方向
  • 五、 Camera 使用流程
  • 六、 Camera 动态权限申请
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档