Android Camera2预览偶尔会旋转90度

时间:2017-04-17 23:02:59

标签: android rotation android-camera2

我正在使用Android的Camera2 API处理某个应用。到目前为止,我已经能够在TextureView内显示预览。该应用程序默认为横向模式。使用模拟器时,预览将显示为颠倒。在我的物理Nexus 5上,预览通常正确显示(风景,而不是颠倒),但偶尔会旋转90度,但仍然会延伸到屏幕的尺寸。 我认为应该很容易,并认为以下代码将返回有关当前方向的必要信息:

// display rotation
getActivity().getWindowManager().getDefaultDisplay().getRotation();
// sensor orientation
mManager.getCameraCharacteristics(mCameraId).get(CameraCharacteristics.SENSOR_ORIENTATION);

...当我看到上面的代码始终为显示器旋转返回1而传感器方向返回90时,我感到非常惊讶,无论< / em>预览被旋转90度。 (在仿真器内,传感器方向始终为270,如果我假设90是正确的方向,则有意义)。 我还检查了AutoMeasureTextureViewonMeasureonMeasure内的宽度和高度(从Android's Camera2 example采用),我用它来创建我的TextureView。但是没有运气 - 无论预览轮换如何,onSurfaceTextureSizeChanged内报告的宽度和高度始终相同。 所以我对如何解决这个问题毫无头绪。有没有人知道在我的预览方向偶尔会有什么原因可能是什么原因?

[编辑] 我刚刚发现的一个细节:每当预览出现时,TextureView.SurfaceTextureListener中的onSurfaceTextureSizeChanged似乎都没有被调用。在SurfaceTexture的文档中,只要createCameraPreviewSession的缓冲区大小发生变化,就会调用此方法。我有一个方法texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); (复制自Android&#29的Camera2示例),其中我设置了纹理的默认缓冲区大小,如

onSurfaceTextureSizeChanged

从我的日志记录输出中我可以看出element之后被完全调用 - 但是,并非总是......(或者设置默认缓冲区大小有时会无声地失败?)。

3 个答案:

答案 0 :(得分:3)

我想我可以回答我自己的问题:我在Android's Camera2 example之后创建了我的Camera2片段。但是,我并没有真正认为方法configureTransform很重要,因为与示例代码相反,我的应用程序无论如何都被强制为横向模式。原来,这个假设是错误的。由于configureTransform重新整合到我的代码中,我没有经历过任何更多的打嗝。

更新:Android文档页面中的原始示例似乎不再存在。我已经更新了现在指向Github上的代码的链接。

答案 1 :(得分:1)

我在Nexus设备上也遇到了类似的问题.Below代码对我有用。 在打开相机之前调用此功能。还有Resume()。

private void transformImage(int width,int height)   {

    if (textureView == null) {

        return;
    } else try {
        {
            Matrix matrix = new Matrix();
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            RectF textureRectF = new RectF(0, 0, width, height);
            RectF previewRectF = new RectF(0, 0, textureView.getHeight(), textureView.getWidth());
            float centerX = textureRectF.centerX();
            float centerY = textureRectF.centerY();
            if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
                previewRectF.offset(centerX - previewRectF.centerX(), centerY - previewRectF.centerY());
                matrix.setRectToRect(textureRectF, previewRectF, Matrix.ScaleToFit.FILL);
                float scale = Math.max((float) width / width, (float) height / width);
                matrix.postScale(scale, scale, centerX, centerY);
                matrix.postRotate(90 * (rotation - 2), centerX, centerY);
            }
            textureView.setTransform(matrix);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

答案 2 :(得分:0)

我按照上面列出的整个textureView.setTransform(matrix)方法进行操作。但是,我还能够使用更简单的textureView.setRotation(270)手动设置轮换,而无需创建Matrix