博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Camera2挖坑日记---如何解决预览画面变形
阅读量:5755 次
发布时间:2019-06-18

本文共 1993 字,大约阅读时间需要 6 分钟。

原创文章,转载请联系作者

一梦觉来三十载,休休。空为梅花白了头

概述

Camera2是目前Android相机开发最新的API,旧版本的Camera已经被废弃了。

一般情况下,Camera2的使用是将图像发送到SurfaceView或者TextureView【通过SurfaceTexture】来预览。使用JPEG或者Raw sensor格式的ImageReader来捕获JPEG图像或RAW缓冲区。【注1】
今天主要是记录一下, 在使用Camera2API开发Android相机过程中,解决预览画面变形的问题。
另,本文所记录的情况,都是竖屏情况的设备。
题主参考Google方法给出的Demo,自定义了TextureView,可以自动适配宽高,支持全屏展示。代码地址

效果

以下的画面基本上处于同一角度拍摄所得

  • 变形的画面

  • 正常的小画面,以宽为基准计算高度。

  • 正常全屏画面,高度铺满屏幕,画面被拉近。

解决

++在解决方案上,主要参考了Google官方给出的Demo。++。

Camera2的使用上,我使用了TextureView作为预览画面的承载。为什么不使用SurfaceView呢?因为SurfaceView是基于Window层面的View,有很多View的属性都用不了,使用起来比较麻烦。
Camera2API会返回一系列可以用于输出到SurfaceTexture的Size集合。--++TextureView显示原理即是使用SurfaceTexture构建的Surface++

如图:

以题主手上的Oppo r15为例,总共会返回13个可以用作输出的size
需要注意的是,如果以竖屏为例,这里的宽高是反过来的
在得到可用的size集合后,根据实际开发情况选择合适的PreviewSize即可

正常小画面展示

选定了一个合适的PreviewSize之后,只需要适配TextureView的宽高即可。小画面以宽为基准,需要根据屏幕宽度来计算相应的高度即可。这一部分的代码,在官方Demo里已经相当详细。其实很简单,就是自电影AutoFitTextureView里的onMeasure函数里,重新设定宽高。

override fun onMeasure(....){    if (width < ((height * ratioWidth) / ratioHeight)) {            // 控件本身的宽小于根据比例计算来得宽,则使用控件本身的宽        setMeasuredDimension(width, (width * ratioHeight) / ratioWidth)    } else {        setMeasuredDimension((height * ratioWidth) / ratioHeight, height)    }}复制代码

其中ratioWidth、ratioHeight即是PreviewSize

全屏展示

全屏展示预览画面,则需要使用TextureView的另一个函数——setTransform。这个函数是给Textureview设置一个Transform,用于改变TextureView的画面。By,双指缩放时可以使用这个函数。

全屏展示时,TextureView的宽高铺满整个屏幕,相应的我们只需要改变一下Transform即可,此时高度不变,但是要将画面的宽度放大。放大的倍数即为屏幕的高度除以小画面时计算得来的高度比例即可。
还是在onMeasure函数内:

override fun onmeasure(...){    val w = resources.displayMetrics.widthPixels    val h = resources.displayMetrics.heightPixels    setMeasuredDimension(w, h)    fullScreenTransform.reset()    fullScreenTransform.set(defTransform)    // 宽拉伸,高不变    fullScreenTransform.postScale(h.toFloat() /ratioHeight,                    1f, w * 0.5f, h * 0.5f)    setTransform(fullScreenTransform)}复制代码

其中fullScreenTransform即为TextureView最初始的Transform

自定义TextureView

题主将AutoFitTextureView重新封装了一下,对外提供了全屏展示的开关函数。地址在这里,感兴趣的童鞋可以去看一下。

以上

你可能感兴趣的文章
为eclipse安装maven插件
查看>>
公司新年第一次全员大会小记
查看>>
最懒的程序员
查看>>
JAVA8 Stream 浅析
查看>>
inner join on, left join on, right join on要详细点的介绍
查看>>
SAS vs SSD对比测试MySQL tpch性能
查看>>
Spring boot 整合CXF webservice 全部被拦截的问题
查看>>
Pinpoint跨节点统计失败
查看>>
【Canal源码分析】Canal Server的启动和停止过程
查看>>
机房带宽暴涨问题分析及解决方法
查看>>
iOS 绕过相册权限漏洞
查看>>
我的友情链接
查看>>
XP 安装ORACLE
查看>>
八、 vSphere 6.7 U1(八):分布式交换机配置(vMotion迁移网段)
查看>>
[转载] 中华典故故事(孙刚)——19 万岁
查看>>
修改hosts文件里面的主机名,oralce asm无法启动
查看>>
Maven学习总结(十)——使用Maven编译项目gbk的不可映射问题
查看>>
php5编译安装常见错误和解决办法集锦
查看>>
Linux远程访问及控制
查看>>
MongoDB实战系列之五:mongodb的分片配置
查看>>