你真的懂了Camera的尺寸参数了吗?

本文针对自定义相机开发中,使用opengl渲染时,引发的最终视图变形问题


开发相机的过程中,你是否遇到过你想要的是右边图效果,结果出来的却是左边图效果,如果你遇到了,本文你遇到的问题或许有帮助;引发上面的不同效果,就是因为一些列的尺寸所引发的问题。


自定义相机大致框架


一般来说,自定义相机设计如上图:

  1. 底层camera配置好预览参数、方向等尺寸以及配置预览回调到SurfaceTexture,同时创建新纹理并绑定到SurfaceTexture上
  2. 第一步预览开启时,数据会流到SurfaceTexture的纹理上,将其绘制在上图中间的FBO上,在FBO里面我们可以完成自定义相机的内容,比如滤镜、分屏、美颜等各种特效
  3. 取出上一步FBO的附着纹理id,将此纹理绘制到上图最右边View提供的渲染环境中去,最终显示到屏幕上

但是,在上面渲染的时候三个地方的尺寸各自代表什么意思?他们之间又有什么关系?
他们的确有关系,如果处理不当,最终view上显示的图像就会变形


size解释

  • Camera

期望尺寸expect: 我们期望相机预览输出的尺寸,比如1920*1680;但是最终相机预览尺寸不一定是我们期望的expect,不一定相等

预览尺寸preview: Android Camera都有自己固定的多种预览尺寸,,前后摄像头预览尺寸也尽不相同,我们需要根据我们期望的尺寸与预览尺寸对比,从中选择出适合我们的预览尺寸

旋转角度: Android相机都是有角度的,我们需要设置角度使我们的图像看起来是正常方向;而且根据横竖屏方向,适当调整宽高(宽变高,高变宽)

预览数据长度: Android相机大部分数据格式都是YUV420,只是存储格式会有平面、压缩模式,YV12、YU12、NV12和NV21,而且数据长度肯定是预览尺寸乘积,再乘3/2

  • FBO
    帧缓冲对象FBO在创建附着纹理,以及渲染时窗口需要高宽尺寸参数,这个参数是多少呢?一般来说没有限制,但是为了能够接住camera那边传递过来的所有数据,至少要比预览尺寸大

  • View视图
    这边来说,一般view尺寸布局时就固定了的,这个尺寸最终要用到渲染最后一级图像时,渲染整个窗口时使用,纹理则使用上一级FBO的附着纹理进行绘制即可

上述会引发几个问题?

  1. 如何根据期望尺寸expect,去Camera的众多预览尺寸中去选择合适的尺寸?
  2. 如何设置相机角度?
  3. 预览尺寸数据长度是如何去计算?
  4. 最后尺寸之间联系如何?

如何根据期望尺寸expect,去Camera的众多预览尺寸中去选择合适的尺寸?

以下只是提供思路:

  1. 期望尺寸宽高比逐一与预览尺寸宽高比对比,查看是否相等,相等就可以选择,如果相等的有很多,可以在从中选择最小、最大或者居中的尺寸;但是越大分辨率越高,最后预览回调的数据data越多,处理也越耗时
List<Camera.Size> useableSize = new ArrayList<>();
for (Camera.Size size : sizes) {if (size.height * expectWidth / expectHeight == size.width) {useableSize.add(size);}
}
  1. 如果宽高比都没有一致的,那可以按照以下几个规则去选择:
  • 期望尺寸乘积和预览尺寸乘积接近的
  • 期望宽和预览宽相等或者接近的
  • 期望高和预览高相等或者接近的

如何设置相机角度

Camera都会有一个默认的角度,如果不设置相机角度,直接输出的图片会不那么正,所以我们要调整这个角度

Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(camerId, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {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;
} else {result = (info.orientation - degrees + 360) % 360;
}
//以下camera是打开Camera后的相机索引
camera.setDisplayOrientation(result);

预览回调数据长度是如何计算的?

首先,你得知道什么是YUV420?
我们知道预览尺寸就是显示的分辨率,假如一张YUV格式的图分辨率为100 * 100,那么就有100 * 100个像素点,每个像素点由三个通道Y U V,明亮程度和颜色差值构成,420是比例,U V在宽高上都只有Y的一半,所以Y有100 * 100, U只有100 * 100 /4 ,V和U一样,最终加起来就是100 * 100 * 3 / 2;


尺寸关系?

  1. 根据上面章节如何根据期望尺寸,选择预览尺寸,得到预览尺寸
  2. 根据相机角度,竖屏要调整宽高,这个宽高值选择的预览宽高
  3. 将FBO宽高设置为预览宽高,因为要装下所有的数据,第二步已经通过相机角度调整了宽高,这里就不用调整宽高了
  4. 最后渲染到view,使用视图View宽高即可

更多精彩博文,加入我们,一同进步!

你真的懂了Camera的尺寸参数了吗?相关推荐

  1. “三次握手,四次挥手”你真的懂吗?

    来源:码农桃花源 解读:"拼多多"被薅的问题出在哪儿?损失将如何买单? 之前有推过一篇不错的干货<TCP之三次握手四次挥手>,前几天有兄弟投稿,开始还以为是同一篇,后经 ...

  2. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...

    程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...

  3. 【原创】“三次握手,四次挥手”你真的懂吗?

    记得刚毕业找工作面试的时候,经常会被问到:你知道"3次握手,4次挥手"吗?这时候我会"胸有成竹"地"背诵"前期准备好的"答案&qu ...

  4. 你真的懂TensorFlow吗?Tensor是神马?为什么还会Flow?

    本文的ipynb 格式见CSDN下载. 0维张量/标量 标量是一个数字 1维张量/向量 1维张量称为"向量". 2维张量 2维张量称为矩阵 3维张量 公用数据存储在张量 时间序列数 ...

  5. 关于Spring底层原理面试的那些问题,你是不是真的懂Spring?

    转载自  关于Spring底层原理面试的那些问题,你是不是真的懂Spring? 1.什么是 Spring 框架?Spring 框架有哪些主要模块? Spring 框架是一个为 Java 应用程序的开发 ...

  6. 你真的懂Redis的5种基本数据结构吗?

    摘要: 你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看. 本文分享自华为云社区<你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看>,作者:李子捌. 一 ...

  7. 技术科普丨黑电平:你真的懂“黑”吗?

    技术科普丨黑电平:你真的懂"黑"吗? 转载于:技术科普丨黑电平:你真的懂"黑"吗? 第27期 "眼前的黑不是黑,你说的白是什么白-" 不知你 ...

  8. 关于GPIO你真的懂了吗?这篇文章都给你整理好了

    关于GPIO你真的懂了吗? 一.前言 二.GPIO内部结构 三.输入输出模式 3.1 浮空输入 3.2 上拉输入模式 3.3 下拉输入模式 3.4 模拟输入模式 3.5 开漏输出模式 3.6 开漏复用 ...

  9. vue作用域插槽,你真的懂了吗?

    前言 在网上搜了很多关于作用域插槽的解释,感觉没有写得很具体的吧,我认为应该对组件化有很深的理解才会触及到这个问题吧,这里也分享下我自己对于slot-scope的一点理解. slot大家看看文档都懂了 ...

最新文章

  1. 屏幕按压力度android,android手机 N 所支持的压感技术
  2. 系统聚类(hierarchical clustering analysis)
  3. html画布360图案填充_在Photoshop中创建带有图案的抽象设计
  4. python背诵技巧_python如何记忆方法
  5. 2018 蓝桥杯省赛 B 组模拟赛(五)题 G题
  6. 02: python3使用email和smtplib库发送邮件
  7. fastmock模拟常见数据结构
  8. T-SQL DATEPART() Functions
  9. 服务器常见问题:服务器使用过程中感觉不流畅、卡顿
  10. Mysql创建用户并赋予权限
  11. 程序员必备的6个好习惯,成为更优秀的自己
  12. html 环形图圆角,canvas绘制圆角环形图
  13. 新手如何Reverces(基础ctf教程篇)
  14. 111完美邮箱品牌域名——数字域名111.com
  15. C语言和win32绿色鼠标连点器,带代码(Windows)
  16. javaweb JSP JAVA 电影院在线订票系统(电影购票系统 电影售票 电影票预订系统)(支持在线选座)
  17. Excel表格转为Latex图表
  18. 基于Win10单机部署kubernetes应用
  19. 洛谷 2448 无尽的生命
  20. 因果信号的傅里叶变换_信号与系统实验报告3实验3 傅里叶变换及其性质

热门文章

  1. Ceph client上配置RBD log
  2. OGame的建筑说明
  3. 基于Python+C++的二维碎片图像拼接复原系统
  4. pdf如何添加水印以及删除水印方法介绍
  5. 英文小论文怎么查重?
  6. word双栏里面插入单栏的图片如何操作
  7. pytorch实现LSTM学习总结
  8. laravel migrations 反向生成
  9. 四驾马车:从“制造之城”到“智能制造之都”的长沙缘何飞速前进
  10. ubuntu 14.04 安装网卡驱动