你真的懂了Camera的尺寸参数了吗?
你真的懂了Camera的尺寸参数了吗?
本文针对自定义相机开发中,使用opengl渲染时,引发的最终视图变形问题
开发相机的过程中,你是否遇到过你想要的是右边图效果,结果出来的却是左边图效果,如果你遇到了,本文你遇到的问题或许有帮助;引发上面的不同效果,就是因为一些列的尺寸所引发的问题。
自定义相机大致框架
一般来说,自定义相机设计如上图:
- 底层camera配置好预览参数、方向等尺寸以及配置预览回调到SurfaceTexture,同时创建新纹理并绑定到SurfaceTexture上
- 第一步预览开启时,数据会流到SurfaceTexture的纹理上,将其绘制在上图中间的FBO上,在FBO里面我们可以完成自定义相机的内容,比如滤镜、分屏、美颜等各种特效
- 取出上一步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的附着纹理进行绘制即可
上述会引发几个问题?
- 如何根据期望尺寸expect,去Camera的众多预览尺寸中去选择合适的尺寸?
- 如何设置相机角度?
- 预览尺寸数据长度是如何去计算?
- 最后尺寸之间联系如何?
如何根据期望尺寸expect,去Camera的众多预览尺寸中去选择合适的尺寸?
以下只是提供思路:
- 期望尺寸宽高比逐一与预览尺寸宽高比对比,查看是否相等,相等就可以选择,如果相等的有很多,可以在从中选择最小、最大或者居中的尺寸;但是越大分辨率越高,最后预览回调的数据data越多,处理也越耗时
List<Camera.Size> useableSize = new ArrayList<>();
for (Camera.Size size : sizes) {if (size.height * expectWidth / expectHeight == size.width) {useableSize.add(size);}
}
- 如果宽高比都没有一致的,那可以按照以下几个规则去选择:
- 期望尺寸乘积和预览尺寸乘积接近的
- 期望宽和预览宽相等或者接近的
- 期望高和预览高相等或者接近的
如何设置相机角度
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;
尺寸关系?
- 根据上面章节如何根据期望尺寸,选择预览尺寸,得到预览尺寸
- 根据相机角度,竖屏要调整宽高,这个宽高值选择的预览宽高
- 将FBO宽高设置为预览宽高,因为要装下所有的数据,第二步已经通过相机角度调整了宽高,这里就不用调整宽高了
- 最后渲染到view,使用视图View宽高即可
更多精彩博文,加入我们,一同进步!
你真的懂了Camera的尺寸参数了吗?相关推荐
- “三次握手,四次挥手”你真的懂吗?
来源:码农桃花源 解读:"拼多多"被薅的问题出在哪儿?损失将如何买单? 之前有推过一篇不错的干货<TCP之三次握手四次挥手>,前几天有兄弟投稿,开始还以为是同一篇,后经 ...
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...
- 【原创】“三次握手,四次挥手”你真的懂吗?
记得刚毕业找工作面试的时候,经常会被问到:你知道"3次握手,4次挥手"吗?这时候我会"胸有成竹"地"背诵"前期准备好的"答案&qu ...
- 你真的懂TensorFlow吗?Tensor是神马?为什么还会Flow?
本文的ipynb 格式见CSDN下载. 0维张量/标量 标量是一个数字 1维张量/向量 1维张量称为"向量". 2维张量 2维张量称为矩阵 3维张量 公用数据存储在张量 时间序列数 ...
- 关于Spring底层原理面试的那些问题,你是不是真的懂Spring?
转载自 关于Spring底层原理面试的那些问题,你是不是真的懂Spring? 1.什么是 Spring 框架?Spring 框架有哪些主要模块? Spring 框架是一个为 Java 应用程序的开发 ...
- 你真的懂Redis的5种基本数据结构吗?
摘要: 你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看. 本文分享自华为云社区<你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看>,作者:李子捌. 一 ...
- 技术科普丨黑电平:你真的懂“黑”吗?
技术科普丨黑电平:你真的懂"黑"吗? 转载于:技术科普丨黑电平:你真的懂"黑"吗? 第27期 "眼前的黑不是黑,你说的白是什么白-" 不知你 ...
- 关于GPIO你真的懂了吗?这篇文章都给你整理好了
关于GPIO你真的懂了吗? 一.前言 二.GPIO内部结构 三.输入输出模式 3.1 浮空输入 3.2 上拉输入模式 3.3 下拉输入模式 3.4 模拟输入模式 3.5 开漏输出模式 3.6 开漏复用 ...
- vue作用域插槽,你真的懂了吗?
前言 在网上搜了很多关于作用域插槽的解释,感觉没有写得很具体的吧,我认为应该对组件化有很深的理解才会触及到这个问题吧,这里也分享下我自己对于slot-scope的一点理解. slot大家看看文档都懂了 ...
最新文章
- 屏幕按压力度android,android手机 N 所支持的压感技术
- 系统聚类(hierarchical clustering analysis)
- html画布360图案填充_在Photoshop中创建带有图案的抽象设计
- python背诵技巧_python如何记忆方法
- 2018 蓝桥杯省赛 B 组模拟赛(五)题 G题
- 02: python3使用email和smtplib库发送邮件
- fastmock模拟常见数据结构
- T-SQL DATEPART() Functions
- 服务器常见问题:服务器使用过程中感觉不流畅、卡顿
- Mysql创建用户并赋予权限
- 程序员必备的6个好习惯,成为更优秀的自己
- html 环形图圆角,canvas绘制圆角环形图
- 新手如何Reverces(基础ctf教程篇)
- 111完美邮箱品牌域名——数字域名111.com
- C语言和win32绿色鼠标连点器,带代码(Windows)
- javaweb JSP JAVA 电影院在线订票系统(电影购票系统 电影售票 电影票预订系统)(支持在线选座)
- Excel表格转为Latex图表
- 基于Win10单机部署kubernetes应用
- 洛谷 2448 无尽的生命
- 因果信号的傅里叶变换_信号与系统实验报告3实验3 傅里叶变换及其性质