【问题标题】:Camera2 front camera preview rotationCamera2前置摄像头预览旋转
【发布时间】:2015-12-10 13:37:04
【问题描述】:

我正在使用 camera2,但遇到了旋转问题。 在某些设备中,切换到前置摄像头时,预览会旋转 180 度。 正在为 camera2 寻找这样的“setDefaultOrientation()”方法,但找不到。

谢谢

【问题讨论】:

  • 你用什么来显示你的预览? SurfaceView 或 TextureView,还是别的什么?
  • 我正在使用 GLSurfaceView。我的应用程序中的方向是固定的,它是横向的,当相机切换到前面时,旋转问题并非在所有设备上都存在。

标签: android rotation orientation camera2


【解决方案1】:

使用 GLSurfaceView,您大概是在使用 SurfaceTexture 将相机预览流映射到 GL 纹理,然后渲染它。

纹理中的图像数据不会自动旋转为“直立” - 一方面,操作系统无法知道您将如何渲染纹理。

但是,SurfaceTexture 有一个 getTransformMatrix 调用,当连接到 camera2 API 时,它将为您提供从相机方向到设备的本机方向的必要转换(通常是手机的纵向,平板电脑的风景,但并非总是如此)。然后,您必须将本机方向到应用程序方向的转换添加到此矩阵,然后应用组合矩阵转换来调整预览图像。

【讨论】:

  • 感谢 Eddy,我这样做并解决了问题,但它导致旧相机预览的旋转错误(低于 API 21)。有没有其他解决方案?
  • 对于旧的相机API,您需要使用setDisplayOrientation调用(developer.android.com/reference/android/hardware/…);文档中有设置完整转换的示例代码(不需要另外考虑应用程序方向)。
  • @user0770 你能分享这段代码吗?我也遇到了同样的问题。
  • 看看github.com/google/cameraview,它使用了一个或多或少相同的TextureView,特别是它是如何设置变换矩阵的:github.com/google/cameraview/blob/master/library/src/main/api14/…
  • @siva 14 ,这里肯定是其中的一部分:private SurfaceTexture mSurfaceTexture;用创建的纹理 ID 新建它: mSurfaceTexture = new SurfaceTexture(mCameraTexture.getTextureId());设置监听器:mSurfaceTexture.setOnFrameAvailableListener(this);并得到它的矩阵: mSurfaceTexture.getTransformMatrix(mTransformM);其中 mTransformM 是新的浮点数[16];不要忘记在需要的地方调用 mSurfaceTexture.updateTexImage() 。希望这会有所帮助。
【解决方案2】:

您可以在使用CameraCharacterisitics 捕获CameraCaptureSession.StateCallback 中的图像时在CaptureRequest 对象中设置正确的图像旋转

CameraCharacterisitics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);

像这样。

private CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
  captureSession = session;
  try {
    CaptureRequest.Builder builder = session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
    builder.addTarget(imageReader.getSurface());
    builder.set(CaptureRequest.JPEG_ORIENTATION, cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION));
    session.capture(builder.build(), null, backgroundHandler);
  } catch (CameraAccessException e) {
    Log.d("tag", e.getMessage());
  }
}

@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
};

【讨论】:

  • 这是拍摄的图像,我需要预览
【解决方案3】:

你可以试试这个代码来打开你的相机

我希望这会有所帮助

public void startPreview() {
    try {
        Log.i(TAG, "starting preview: " + started);

        // ....
        Camera.CameraInfo camInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraIndex, camInfo);
        int cameraRotationOffset = camInfo.orientation;
        // ...

        Camera.Parameters parameters = camera.getParameters();
        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
        Camera.Size previewSize = null;
        float closestRatio = Float.MAX_VALUE;

        int targetPreviewWidth = isLandscape() ? getWidth() : getHeight();
        int targetPreviewHeight = isLandscape() ? getHeight() : getWidth();
        float targetRatio = targetPreviewWidth / (float) targetPreviewHeight;

        Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio);
        for (Camera.Size candidateSize : previewSizes) {
            float whRatio = candidateSize.width / (float) candidateSize.height;
            if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) {
                closestRatio = whRatio;
                previewSize = candidateSize;
            }
        }

        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
        case Surface.ROTATION_0:
            degrees = 0;
            break; // Natural orientation
        case Surface.ROTATION_90:
            degrees = 90;
            break; // Landscape left
        case Surface.ROTATION_180:
            degrees = 180;
            break;// Upside down
        case Surface.ROTATION_270:
            degrees = 270;
            break;// Landscape right
        }
        int displayRotation;
        if (isFrontFacingCam) {
            displayRotation = (cameraRotationOffset + degrees) % 360;
            displayRotation = (360 - displayRotation) % 360; // compensate
                                                                // the
                                                                // mirror
        } else { // back-facing
            displayRotation = (cameraRotationOffset - degrees + 360) % 360;
        }

        Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = "
                + displayRotation);

        this.camera.setDisplayOrientation(displayRotation);

        int rotate;
        if (isFrontFacingCam) {
            rotate = (360 + cameraRotationOffset + degrees) % 360;
        } else {
            rotate = (360 + cameraRotationOffset - degrees) % 360;
        }

        Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate);

        Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height);
        parameters.setPreviewSize(previewSize.width, previewSize.height);
        parameters.setRotation(rotate);
        camera.setParameters(parameters);
        camera.setPreviewDisplay(mHolder);
        camera.startPreview();

        Log.d(TAG, "preview started");

        started = true;
    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多