android-camera方向

2023-05-16

1、概念解释。

“自然方向”:指当宽比高短时,我们看到的手机的方向(竖屏),就是自然方向。

2、相机图像传感器采集图像的方向。

由于手机Camera拍摄到的图片来自相机的图像传感器,而相机是固定到手机上的,所以相机的图像传感器的图像采集方向就固定住了。因此只能对采集后的图片数据进行旋转以便得到正确的预览。

3、图像校正,进行预览旋转。

        我们可以通过CameraInfo对象的Orientation属性获取图像传感器的图像采集方向,该属性是一个角度值,只能有0,90,180,270四个中的一个,这几个角度值是相对于手机的“自然方向”来说的。再直白点就是,相机所采集的图像只要按着该角度顺时针旋转就可以得到正确的预览图像数据。

       然后通过Camera的setDisplayOrientation方法改变预览方向(顺时针旋转)。后置摄像头为90,前置摄像头的Orientation通常为270。所以,当是后置摄像头时,setDispayOrientation(90)即可将预览图像校正,及顺时针旋转90。而当是前置摄像头时,设置270就不行了,因为前置摄像头会在旋转预览方向之前,对预览方向来一个水平翻转,所以设置值应该是90,及顺时针旋转90。

4、图解演示旋转过程。

(1)手机自然方向如下:

 

(2)后置摄像头传感器采集的图像如下:

所以只要顺时针旋转90度即可。

(3)前置摄像头传感器采集的图像如下:

 接下来进行旋转校正

 5、根据相机情况与屏幕情况进行计算得到最终orientation,用于预览校正。

public void setCameraDisplayOrientationNew(Activity activity){
        Camera.CameraInfo cameraInfo=new Camera.CameraInfo();
        Camera.getCameraInfo(CameraId,cameraInfo);
        //当前屏幕的方向,0为自然方向,1为顺时针旋转90,2为顺时针180,3为顺时针270
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        int degree=0;//当前手机顺时针旋转的角度
        switch (rotation){
            case Surface.ROTATION_0:
                degree=0;
                break;
            case Surface.ROTATION_90:
                degree=90;
                break;
            case Surface.ROTATION_180:
                degree=180;
                break;
            case Surface.ROTATION_270:
                degree=270;
                break;
        }
        int result;
        if(cameraInfo.facing== Camera.CameraInfo.CAMERA_FACING_FRONT){//前置
            //前置摄像头会进行水平镜像旋转(逆时针旋转180)
            result= (cameraInfo.orientation + 180-degree)%360;
        }else{
            //后置摄像头无需水平翻转,直接是差值
            result = (cameraInfo.orientation - degree +360 )%360;
        }
        mCamera.setDisplayOrientation(result);
    }


6、上面的算法,也或许看不懂,没关系,接下来详细介绍一下用到的各个方向。

(1)、Activity的Rotation

在Activity中,提供了一个接口,可以获取当前手机的旋转角度。

getWindowManager().getDefaultDisplay().getRotation();
这个接口返回的值主要有如下4个:

Surface.ROTATION_0,

Surface.ROTATION_90,

Surface.ROTATION_180,

Surface.ROTATION_270

依次代表手机的方向如下:

 

对于Activity,默认的手机方向时:竖屏Home键在下面,这个方向是Activity的0度方向。

注意:它的角度规律是:“逆时针”方向旋转递增,每次递增90度。

(2)、传感器得到的屏幕方向

通过OrientationEventListener类,监听传感器给出的信息来确定屏幕的方向,这个方法得到的方向比较准确,而且多少度角度都可以得到,而不是固定0、90、180、270。及它不需要等待手机旋转了90度才会有反应,而是在手机旋转了任何角度的时候,都会回调onOrientationChanged告诉你当前手机的角度,当然,如果你只希望得到4个角度的变化事件,可以自己在该函数中做判断。调用函数如下:

mOrientationListener = new OrientationEventListener(this,
                SensorManager.SENSOR_DELAY_NORMAL) {
 
            @Override
            public void onOrientationChanged(int orientation) {
                Log.v("haha","Orientation changed to " + orientation);
            }
        };
 
        if (mOrientationListener.canDetectOrientation()) {
            Log.v(TAG, "Can detect orientation");
            mOrientationListener.enable();
        } else {
            Log.v(TAG, "Cannot detect orientation");
            mOrientationListener.disable();
        }

它的值分别对应的手机方向如下:

 

对于Sensor,默认的手机方向是:竖屏Home键在下面,这个是Sensor的0度方向。

注意:它的角度递增规律是:“顺时针”方向旋转,每次递增90度。

(3)、相机的Preview方向

Camera通过setDisplayOrientation来设置预览角度,各值对应手机方向如下:

 

对于Camera,默认情况下,手机横屏,HOME键在右边,这个方向是Camera的0度方向。

注意:它的角度递增规律是:“顺时针”方向旋转,每次递增90度。

所以,对于不管是前置还是后置摄像头,对应屏幕上述的各个方向,设置预览角度就可以得到校正后的预览图像。

接下来具体分析一下:

通过上述给的算法公式获得preview与上述要求的相机的Preview方向正好对应,说明该公式正确。可以使相机预览方向正确。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android-camera方向 的相关文章

  • Android 中读取未提交的事务

    我正在进行大量数据库操作 这会向我的数据库添加大约 10 000 条记录 由于这可能需要很长时间 因此最好使用事务 db startTransaction do write operations db setTransactionSucce
  • onBackPressed 仅关闭 ProgressDialog

    我意识到我的异步任务有一个小问题 我意识到 当我按 Android 设备上的后退按钮来关闭进度对话框和异步任务时 只有我的进度对话框被关闭 而我的异步任务仍在执行 我真的不知道为什么会发生这种情况 所以我只是希望有人能让我回到正确的轨道并帮
  • Android Wear:在手持设备上启动服务

    我正在构建一个 Wear 应用程序 它将与手持设备上的 WearableListenerService 进行通信 但是 我想确保当应用程序在手表上启动时服务已启动并运行 我最初的想法是发送意图或广播消息来启动服务 但是 我一直无法弄清楚如何
  • 在 Android strings.xml 文件中使用 HREF

    我正在尝试从 strings xml 文件中为 TextView android text 属性分配以下字符串 我无法让链接显示为可点击的超链接 有什么建议么 我尝试过以下技术
  • 将片段部分移出屏幕

    我已经被这个问题难住有一段时间了 我试图将包含在 FrameLayout 中的片段向右移动 以便只有片段的左侧 20 可见 我认为我遇到的问题是父级不会让片段移出其边界 或者我不知道如何移动它 我所尝试的一切只是将片段推到右墙上 然后缩放片
  • 在styles.xml中设置所有按钮样式

    我想让我的应用程序有多种样式 样式更改按钮样式 文本视图颜色和布局背景颜色 我的按钮样式位于 xml 文件中 这是我的代码 style xml v21
  • Android Surface 与 Canvas 的关系

    Surface 和 Canvas 之间到底是什么关系 请解释 表面是一个缓冲区 画布保存绘图 视图未附加到画布 也不是表面 窗户被绑在 Surface 和 ViewRoot 询问 随后使用的画布表面 通过要绘制的视图 详细答案你可以阅读这篇
  • 如何在Android中将文件转换为base64(如.pdf、.text)?

    如何将 SD 卡文档 pdf txt 转换为 Base 64 字符串并将字符串发送到服务器 这个方法对我有用 String encodeFileToBase64Binary encodeFileToBase64Binary yourFile
  • 在我授予许可后,表面视图不显示相机

    public View onCreateView LayoutInflater inflater Nullable ViewGroup container Bundle savedInstanceState View view inflat
  • cordova - 删除不必要的权限

    我需要在游戏中播放声音 因此我将 org apache cordova media 插件添加到我的应用程序中 现在platforms android AndroidManifest xml包含2个我不需要的条目
  • Android EditText默认数字键盘和允许文本[重复]

    这个问题在这里已经有答案了 可能的重复 EditText 默认带有数字键盘 但允许字母字符 https stackoverflow com questions 3544214 edittext with number keypad by d
  • Android - 对话框内VideoView的MediaController出现在对话框后面

    我有一个VideoView在自定义对话框中 我正在为VideoView即时并将其分配给VideoView在代码中 但是控制器实际上并没有出现在视频上 它出现在对话框后面 知道如何让控制器位于视频上方吗 我创建了一个静态对话框帮助器类来帮助构
  • Android键盘点击搜索输入时出现和消失

    我在用谷歌地图 Js API当我搜索一个地方时 我的输入搜索栏工作正常 当我通过 iPhone 设备使用它时 它也工作得很好 但是当我通过Android 设备然后键盘立即出现和消失 我已经找到了一些关于当我按下搜索栏时 android 键盘
  • Android 原生 AAssetManager 的文件层次结构

    Issue 我想知道如何从本机代码创建 Android 中资产文件夹的文件层次结构 我在用着AAssetManager openDir but AAssetDir getNextFileName不返回任何目录名称 因此基本上我无法深入了解层
  • 有没有办法在 iOS 上获取相机流的亮度级别?

    我正在使用 iPhone iPad 摄像头获取视频流并在视频流上进行识别 但随着光照的变化 它会对鲁棒性产生负面影响 我已经在不同的光线下测试了不同的设置 并且可以让它工作 但尝试在运行时调整设置是我所需要的 我可以对每一帧进行简单的亮度检
  • Android 中 Activity 的服务回调

    我有我的 GPSTracker 的摘要 它返回用户的位置 其作品 public class GPSTracker extends Service implements LocationListener public GPSTracker C
  • Android Studio:src/androidTest 和 src/main 文件夹之间的区别?

    我是 Android Studio 的新手 我的问题是 src androidTest 和 src main 文件夹有什么区别 我所有的课程应该放在哪里 Refer Android Studio 概述 http developer andr
  • 我收到“循环依赖”Android Dagger Hilt 错误

    我从头开始检查了所有内容 但找不到错误 我找不到错误 可能是什么 我收到以下编译错误 HomeViewModel java 6 error ComponentProcessor MiscError dagger internal codeg
  • onActivityResult() 在 startActivityForResult() 之后未使用 Intent.ACTION_GET_CONTENT 调用

    我得到了我的主要Activity其中持有不同的Fragment的 一个片段使用户可以打开一个DialogFragment 该对话框打开声音文件列表 并且该对话框还包含一个 添加 按钮 用户应该能够从中添加自己的声音文件 为此 我想使用标准的
  • Android 布局以 开头 [重复]

    这个问题在这里已经有答案了 我是 Android 应用程序开发的初学者 我的问题很简单 我似乎无法确定布局文件夹中的 xml 文件是否应以以下开头 当我制作一个入门项目时 它不存在 但我也在读一本书 上面说它应该在那里 正确的方法是什么 嗯

随机推荐

  • RxJava Hook(钩子)方法

    Hook技术又叫钩子函数 xff0c 在系统没有调用函数之前 xff0c 钩子就先捕获该消息 xff0c 得到控制权 这时候钩子程序既可以改变该程序的执行 xff0c 插入我们要执行的代码片段 xff0c 还可以强制结束消息的传递 RxJa
  • android底层之什么是Zram?

    ZRAM的理解 ZRAM xff08 压缩内存 xff09 的意思是说在内存中开辟一块区域压缩数据 就是说假设原来150MB的可用内存现在可以放下180MB的东西 本身不会提高内存容量和运行速度 只是让后台程序更少被系统砍掉罢了 xff0c
  • rxjava - compose()操作符

    1 问题背景 想要给多个流重复应用 34 一系列 34 相同的操作符 该怎么办 比如 我们使用Rx 43 Retrofit进行网络请求时 都有遇到这样场景 要在io线程中请求数据 在主线程订阅 更新UI 所以必须频繁使用下面这样的代码 su
  • RxJava2 背压

    1 背压 在RxJava中 xff0c 会遇到被观察者发送消息太快以至于它的操作符或者订阅者不能及时处理相关的消息 xff0c 这就是典型的背压 Back Pressure 场景 BackPressure经常被翻译为背压 xff0c 背压的
  • MVVM实现与原理分析

    1 MVVM简介 1 1 MVC amp MVP amp MVVM MVP MVVM与MVP结构类似 xff0c MVP也是通过Presenter将View与Model解耦 不过MVVM是基于观察者模式 xff0c viewModel不持有
  • PCM数据格式

    什么是PCM PCM全称Pulse Code Modulation xff0c 翻译一下是脉冲调制编码 其实大可以不用关心英文释义 xff0c 之所以这么命名是因为一些历史原因 在音视频中 xff0c PCM是一种用数字表示采样模拟信号的方
  • 音频帧大小的计算

    音频aac mp3文档规定 xff1a AAC xff1a 帧大小1024个sample xff0c 采样率为44100Hz 帧播放时长 xff1a acc dur 61 1024 44100 61 0 02322s 61 23 22ms
  • Java多线程系列--join()

    1 join 介绍 join 定义在Thread java中 join 的作用 xff1a 让 主线程 等待 子线程 结束之后才能继续运行 这句话可能有点晦涩 xff0c 我们还是通过例子去理解 xff1a 主线程 public class
  • Android的设计模式-装饰者模式

    1 定义 动态地给一个对象添加一些额外的职责 就增加功能来说 xff0c 装饰模式相比生成子类更为灵活 2 介绍 装饰者模式属于结构型模式 装饰者模式在生活中应用实际上也非常广泛 xff0c 一如一间房 xff0c 放上厨具 xff0c 它
  • android音频焦点Audio Focus

    为了便于理解 xff0c 我们以android的8 0以前的版本为例 xff0c 8 0以后有一定改动 xff0c 但是基本思路一样 关于管理音频焦点 xff08 8 0以前和更高版本 xff09 的官方文档 xff1a https dev
  • Android音频通路的切换

    Android支持多种设备的的输出 一台正常的机子 xff0c 本身就自带话筒 xff0c 扬声器 xff0c 麦克风等多个声音输入输出设备 xff0c 再加上五花八门的外置设备 xff08 通过耳机 xff0c 蓝牙 xff0c wifi
  • Java实现基本数据结构——数组

    数组概念 所谓数组 xff0c 是有序的元素序列 若将有限个类型相同的变量的集合命名 xff0c 那么这个名称为数组名 在数据结构中 xff0c 数组是一种线性表 xff0c 就是数据排列成一条直线一样的结构 在内容空间中 xff0c 数组
  • 块元素居中方式

    1 定位 span class token doctype lt DOCTYPE html gt span span class token tag span class token tag span class token punctua
  • wireshark以太帧的分析

    首先应该明白 xff0c 封装以太帧的位于OSI七层模型的第二层 xff0c 也就是数据链路层 xff0c wireshark可以把完整的以太帧抓起来 xff0c 我们可以清楚的看到 打开wireshark找到自己ip对应的网卡 xff0c
  • 网络协议——七层、五层、四层协议概念及功能分析

    一 7层 7层是指OSI七层协议模型 xff0c 主要是 xff1a 应用层 xff08 Application xff09 表示层 xff08 Presentation xff09 会话层 xff08 Session xff09 传输层
  • 为什么 UDP 头只有 8 个字节

    为什么这么设计 xff08 Why s THE Design xff09 是一系列关于计算机领域中程序设计决策的文章 xff0c 我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点 对具体实现造成的影响 如
  • Java 泛型

    Java 泛型 xff08 generics xff09 是 JDK 5 中引入的一个新特性 泛型提供了编译时类型安全检测机制 xff0c 该机制允许程序员在编译时检测到非法的类型 泛型的本质是参数化类型 xff0c 也就是说所操作的数据类
  • Android 端处理 YUV 数据 - Libyuv 的编译与使用

    在 Android 系统上 Camera 输出的图像一般为 NV21 YUV420SP 系列 格式 当我们想进行录像处理时 会面临两个问题 问题 1 图像的旋转问题 后置镜头 需要旋转 90 前置镜头 需要旋转 270 然后再进行镜像处理
  • YUV420P旋转

    YUV420与YUV420P YUV 和我们熟知的 RGB 类似 xff0c 是一种颜色编码格式 它主要用于电视系统和模拟视频邻域 xff08 如 Camera 系统 xff09 YUV 包含三个分量 xff0c 其中 Y 表示明亮度 xf
  • android-camera方向

    1 概念解释 自然方向 xff1a 指当宽比高短时 xff0c 我们看到的手机的方向 xff08 竖屏 xff09 xff0c 就是自然方向 2 相机图像传感器采集图像的方向 由于手机Camera拍摄到的图片来自相机的图像传感器 xff0c