1

i am working on camera2 and have got a problem with rotation. In some devices, when switching to front camera, preview is being rotated 180 degrees. Was looking such a "setDefaultOrientation()" method for camera2 but couldn't find it.

Thanks

user0770
  • 797
  • 3
  • 11
  • 22
  • What are you using to display your preview? A SurfaceView or a TextureView, or something else? – Eddy Talvala Dec 11 '15 at 19:23
  • I am using GLSurfaceView. Orientation is fixed in my app, it is landscape, and the problem with rotation, when camera is switched to front, is not on all devices. – user0770 Dec 17 '15 at 11:19

3 Answers3

2

With a GLSurfaceView, you're presumably using a SurfaceTexture to map the camera preview stream into a GL texture, and then rendering it.

The image data in the texture is not automatically rotated to be 'upright' - for one, there's no way for the OS to know how you're going to render your texture.

However, the SurfaceTexture has a getTransformMatrix call, which when connected to the camera2 API, will give you the necessary transform from the camera's orientation to the device's native orientation (typically portrait for phones, landscape for tablets, but not always). You'll then have to add the transform from the native orientation to your app's orientation to this matrix, and then apply the combined matrix transform to adjust the preview image.

Eddy Talvala
  • 17,243
  • 2
  • 42
  • 47
  • Thanks Eddy, i did so and problem resolved, but it cause in wrong rotation of old Camera preview (below API 21). Is there any additional solution for that ? – user0770 Dec 21 '15 at 13:32
  • For the old camera API, you need to use the setDisplayOrientation call (http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation%28int%29); there's sample code in the docs that sets the full transform (don't need to additionally account for app orientation). – Eddy Talvala Dec 21 '15 at 19:23
  • @user0770 Can you please share the piece of code? I am also get stucked with the same issue. – Sivakumar Sep 29 '16 at 16:25
  • Take a look at https://github.com/google/cameraview which uses a TextureView, which is more or less the same, and specifically how it sets up the transform matrix: https://github.com/google/cameraview/blob/master/library/src/main/api14/com/google/android/cameraview/TextureViewPreview.java#L109 – Eddy Talvala Sep 30 '16 at 03:18
  • @siva 14 , sure here a part of it: private SurfaceTexture mSurfaceTexture; new it with created texture id: mSurfaceTexture = new SurfaceTexture(mCameraTexture.getTextureId()); set a listener: mSurfaceTexture.setOnFrameAvailableListener(this); and get matrix of it: mSurfaceTexture.getTransformMatrix(mTransformM); where mTransformM is new float[16]; don't forget to call mSurfaceTexture.updateTexImage() where needed. Hope this will help. – user0770 Sep 30 '16 at 06:50
-1

you can set the correct image rotation in CaptureRequest object while capturing an image in CameraCaptureSession.StateCallback using CameraCharacterisitics

CameraCharacterisitics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);

like this.

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) {
}
};
Akash Raghav
  • 1,073
  • 9
  • 19
-3

you can try this code for open your camera

I hope this will help

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());
    }
}
Saif
  • 723
  • 6
  • 21
  • 1
    This is for android.hardware.camera, my question is for android.hardware.camera2. – user0770 Dec 10 '15 at 14:29
  • try this code for help you https://android.googlesource.com/platform/cts/+/7b6aac1a749c6b2b0a5710e0fd5866ea3c24e12f/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java and this demo https://github.com/googlesamples/android-Camera2Raw and https://github.com/MrTillis/Camera2Basic – Saif Dec 11 '15 at 07:07