纵向模式下的相机横向预览

我有一个对话框设计,相机预览应该在纵向模式下的风景(见图片)。 我通过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中裁剪,如果你想实时预览。