纵向模式下的相机横向预览
我有一个对话框设计,相机预览应该在纵向模式下的风景(见图片)。 我通过getOptimalPreviewSize()正确选择预览大小,当我不使用setDisplayOrientation(90)时,我得到这个:
当我使用setDisplayOrientation(90)时,我得到这个:
有没有人有任何想法如何解决它? Android可以做这样的事情吗?
答案(感谢Eddy Talvala):
由于在xml中的凸轮视图处于水平状态时无法处理纵向整个凸轮图片,因此应裁剪。 我决定水平放置,剪下底部的所有东西:
| | | _________ | _____ || || | | || || | ^-^ | || ______ || | \_/ | || | ^-^ ||| | | | || |_\_/_ ||| |__|__| || image || sensor || || || || ||_________|| || < O [] || |___________| device
您应该使用TextureView来指定适合和裁剪的矩阵。 类似的东西(kotlin):
fun camInit() { val camParam = camera.parameters val optimalSize = getOptimalPortraitPreviewSize(camParam.supportedPreviewSizes, width, height) camParam.setPreviewSize(optimalSize.width, optimalSize.height) camera.parameters = camParam camera.setPreviewTexture(surface) val scaleDelta = optimalSize.height - preview.width // for portrait val scaleY: Float = (optimalSize.width.toFloat() - scaleDelta) / preview.height // for portrait val matrix = Matrix() matrix.setScale(1f, scaleY) // 1f cause we fit horizontally preview.setTransform(matrix) camera.startPreview() }
请注意,对于纵向模式,您应该使用特定的getOptimalProtraitPreviewSize(),导致每个人使用获取相机预览最佳尺寸的标准function(使用ASPECT_TOLERANCE和其他function)可以返回一个小尺寸的尺寸。 尝试这样的事情:
fun getOptimalPortraitPreviewSize(sizes: List, previewWidth: Int) { var selectedSize: Camera.Size = sizes[0] for (size in sizes) { // use size's height cause of portrait val currentSizeWidthDelta = abs(size.height - previewWidth) val selectedSizeWidthDelta = abs(selectedSize.height - previewWidth) if (currentSizeWidthDelta < selectedSizeWidthDelta) selectedSize = size } return selectedSize }
图像传感器的长边与装置的长边对齐。
(bad ascii art): ____________ | | | _________ | _____ || || | | || || | | || || | | || || | | || || |_____| || || sensor || || physical || || orientation ||_________|| || < O [] || |___________| device
鉴于此,您无法像这样绘制图像:
_____________ | | | _________ | _____ || || | | || || | | || ______ || | | || |
| | || |______
|_____| || image || sensor || || || || ||_________|| || < O [] || |___________| device
除非你旋转图像(在这种情况下不起来):
_____________ | | | _________ | _____ || || | | || || | ^-^ | || ______ || | \_/ | || | <-\__
| | | || |_<-/__
|__|__| || image || sensor || || || || ||_________|| || < O [] || |___________| device
或者水平拉伸图像,这看起来很糟糕:
_____________ | | | _________ | _____ || || | | || || | ^-^ | || ______ || | \_/ | || | ^___^
| | | || |___|__
|__|__| || image || sensor || || || || ||_________|| || < O [] || |___________| device
或者裁剪图像的一部分,这会大大降低FOV:
_____________ | | | _________ | _____ || || | | || || | ^-^ | || ______ || | \_/ | || | ^-^
| | | || |_\_/__
|__|__| || image || sensor || || || || ||_________|| || < O [] || |___________| device
由于当手机处于横向时,图像传感器是横向的,因此无法在纵向UI中放置横向预览,而没有发生这三种情况之一。 您可能需要在肖像用户界面中进行肖像预览,或者需要裁剪图像。 这不是Android的限制,它只是几何的限制。
如果你想裁剪,你可能想要将相机数据发送到SurfaceTexture,并在OpenGL中裁剪,如果你想实时预览。