12

I am kind of newbie in Android development, so my apologies in advance if my question is trivial. In one part of my app I need a live preview of my rear camera, so I created a custom class which extends SurfaceView and implement SurfaceHolder.Callback (I followed basically the instructions in the android documentation).

Unfortunately, I am testing my app in a Nexus 5x, which I've just realized that it has installed the camera sensor in a reverse way. For that reason, the camera preview of my app when running on my Nexus 5x appears upside down, which is something I dont want.

It seems that the new android.hardware.camera2 API is able to handle this issue automatically. Eventually I'll need to update all my code using this new API, but for now what I need is a quick fix while using the old camera API.

So I was reading out there and I found a piece of code that I would need to introduce in the SurfaceChanged method to workaround this issue. Here it is:

Display display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

        if(display.getRotation() == Surface.ROTATION_0)
        {
            parameters.setPreviewSize(capHeight, capWidth);                           
            camera.setDisplayOrientation(90);
        }

        if(display.getRotation() == Surface.ROTATION_90)
        {
            parameters.setPreviewSize(capWidth, capHeight);                           
        }

        if(display.getRotation() == Surface.ROTATION_180)
        {
            parameters.setPreviewSize(capHeight, capWidth);               
        }

        if(display.getRotation() == Surface.ROTATION_270)
        {
            parameters.setPreviewSize(capWidth, capHeight);
            camera.setDisplayOrientation(180);
        }

        camera.setParameters(parameters);*/

        camera.startPreview();

The problem is that I don't see that something has changed.

Any thoughts?

3 Answers3

9

The 5X camera is not "reverse"; it does report the correct camera orientation in its parameters, so no special workarounds are needed, just make sure you're setting the display orientation correctly:

 public static void setCameraDisplayOrientation(Activity activity,
     int cameraId, android.hardware.Camera camera) {
 android.hardware.Camera.CameraInfo info =
         new android.hardware.Camera.CameraInfo();
 android.hardware.Camera.getCameraInfo(cameraId, info);
 int rotation = activity.getWindowManager().getDefaultDisplay()
         .getRotation();
 int degrees = 0;
 switch (rotation) {
     case Surface.ROTATION_0: degrees = 0; break;
     case Surface.ROTATION_90: degrees = 90; break;
     case Surface.ROTATION_180: degrees = 180; break;
     case Surface.ROTATION_270: degrees = 270; break;
 }

 int result;
 if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
     result = (info.orientation + degrees) % 360;
     result = (360 - result) % 360;  // compensate the mirror
 } else {  // back-facing
     result = (info.orientation - degrees + 360) % 360;
 }
 camera.setDisplayOrientation(result);
}

From http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation%28int%29

Robert Williams
  • 569
  • 3
  • 5
  • 5
    That's correct for the preview but when you want to process the image taken you still need to consider the camera rotation which is 270 compared to 90 on most devices (meaning the image is upside down). – Emanuel Moecklin Apr 16 '16 at 02:15
  • 6
    @EmanuelMoecklin Yes the above code fixes the Camera display but the images shown are still upside down, how can i fix this issue? – user2056563 Apr 21 '16 at 13:29
  • I rotated the image by using OpenCV4Android – Heribert Oct 14 '16 at 09:27
  • @Robert Williams, what is the CameraId in this case? – Euridice01 Jan 11 '17 at 22:21
  • @Euridice01 The same cameraId you pass to [open(int)](https://developer.android.com/reference/android/hardware/Camera.html#open(int)), typically chosen by iterating over number of cameras and selecting the most appropriate by CameraInfo (facing direction e.t.c) – Robert Williams Jan 12 '17 at 09:49
  • 1
    it corrects preview but byte frames are still upside down – user924 May 03 '18 at 06:27
  • @EmanuelMoecklin user2056563 did you find any solutions how to fix it (for byte frames)? – user924 May 03 '18 at 06:29
  • @Heribert but both Core.rotate(mRgba, mRgba, Core.ROTATE_180); & Core.flip(mRgba, mRgba, -1); eat too much CPU - ~12-14 ms, e.g. on my Xiaomi Redmi 4 Prime – user924 May 03 '18 at 07:31
6
if (Build.MODEL.equals("Nexus 5X")){
     // rotate camera 180°
     mCamera.setDisplayOrientation(180);
}

Change 5x to 5X will be ok.

Wan benyu
  • 61
  • 1
  • 1
0

Same here. Since camera2 doesn't support devices < API 21, and don't want to implement the two APIs, it would be nice do get a quick fix.

I'm trying somthing like :

if (Build.MODEL.equals("Nexus 5x")){
     // rotate camera 180°
     mCamera.setDisplayOrientation(180);
}

But can't rotate the display of the camera. Gonna check if there is something to do with the PreviewCallback

Is it a bad thing to use the 2 apis ? As in this topic, it is not recommended : How to use Android's camera or camera2 API to support old and new API versions without deprecation notes?

Community
  • 1
  • 1
Soac
  • 9
  • 2