使用TextureView旋转Camera2 API相机流避免画面裁剪的方法
嘿,这个Camera2旋转后画面裁剪的问题我之前也碰到过,其实核心就是只做了旋转没做适配缩放,导致画面和TextureView尺寸不匹配!给你一个直接解决的方案,针对你的单一竖屏设备场景完全适用:
关键思路
你之前的代码只对TextureView做了旋转,但旋转后的相机预览尺寸(宽高互换了)和你的固定尺寸TextureView不匹配,超出的部分自然就被裁剪了。我们需要在旋转前(矩阵操作里先执行缩放)把画面拉伸到刚好填满TextureView的尺寸。
修改后的代码实现
首先你得提前拿到相机的预览尺寸(就是你在Camera2配置里选的16:9尺寸,比如Size(1920, 1080)),然后修改updateTransform方法:
private fun updateTransform(previewSize: Size) { val matrix = Matrix() val centerX = textureView.width / 2f val centerY = textureView.height / 2f // 旋转90度后,相机预览的宽高会互换 val rotatedPreviewWidth = previewSize.height val rotatedPreviewHeight = previewSize.width // 计算缩放比例,让旋转后的画面刚好填满整个TextureView val scaleX = textureView.width.toFloat() / rotatedPreviewWidth val scaleY = textureView.height.toFloat() / rotatedPreviewHeight // 注意矩阵操作顺序:先缩放,再旋转(post的顺序就是实际执行顺序) matrix.postScale(scaleX, scaleY, centerX, centerY) matrix.postRotate(90f, centerX, centerY) textureView.setTransform(matrix) // 你的TextureView是固定尺寸,这里不需要再修改LayoutParams了 }
额外注意点
- 确认相机预览尺寸:一定要选16:9的横屏尺寸(比如1920x1080、1280x720),这样旋转后再缩放才能保证是你要的横屏比例填充效果。
- TextureView尺寸固定:确保你的TextureView在布局里是固定宽高(比如XML里写死dp,或者代码里设置固定像素值),这样
textureView.width和height才是确定的有效值。 - 调用时机:这个方法要在TextureView尺寸确定后调用(比如
onSurfaceTextureAvailable回调里,或者布局完成后),不然宽高可能为0导致计算错误。
这样修改后,旋转后的画面就会完全拉伸填满你的固定尺寸TextureView,不会再有裁剪问题啦!
内容的提问来源于stack exchange,提问作者Booyaches
相关产品推荐
相关产品推荐

