2

I am rendering camera preview on GLSurfaceView everything works fine but camera preview show upside down on some device specially on Nexus 5X . I have checked this solution Android - Camera preview is sideways . This is my code for handling orientation problem

 private void setCameraDisplayOrientation() {
    Constants.debugLog(TAG_DEBUG, "setCameraDisplayOrientation");
    Constants.debugLog(TAG, "setCameraDisplayOrientation ");

    if (camera == null) {
        Constants.debugLog(TAG + " Owncamera", "setCameraDisplayOrientation - camera null");
        return;
    }

    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(currentCameraId, info);

    WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    int rotation = winManager.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;
    }

    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        this.cameraOrientation = 2;
    } else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
        this.cameraOrientation = 1;
    }

    Constants.debugLog(TAG_DEBUG, "result: " + result + "  this.cameraOrientation == " + this.cameraOrientation);
    Constants.debugLog(TAG, "result: " + result + "  this.cameraOrientation == " + this.cameraOrientation);
    //Log.e("camera_orient", "res: "+ result);
    camera.setDisplayOrientation(result);
}

From the Camera.CameraInfo info class, i can get orientation . For maximum device the values i get on portrait mode is "for front camera = 270, back camera = 90 "" but on Nexus 5X it provide camera orientation 270,270 for both front & back camera. Beside on other devices my camera provide result value 90 for both front and back camera in portrait mode but for Nexus 5x front camera 90 back camera 270. I have also tried by setting value fixed 90 on camera.setDisplayOrientation(90); Nexus 5X device but don't work How to handle this problem so that all device camera orientation will be same and i won't get any rotated image ??

Community
  • 1
  • 1
Md. Sulayman
  • 551
  • 7
  • 20

2 Answers2

1

Try

1. First of all, add methods (writeFile, processImage and getCorrectCameraOrientation) defined below

2. Calculate camera orientation after capturing photo and update onPictureTaken**

@Override
public void onPictureTaken (final byte[] data, final Camera camera) {

    int rotationAngle = getCorrectCameraOrientation (this, info);

3. Create file and update photo angle using rotationAngle

File file = new File (folder, fileName);

try {
    file.createNewFile ();
}
catch (IOException e) {
    e.printStackTrace ();
}

writeFile (data, file);
processImage (file, rotationAngle, compressRatio);

writeFile

public static void writeFile (byte[] data, File file) throws IOException {

    BufferedOutputStream bos = null;

    try {
        FileOutputStream fos = new FileOutputStream (file);
        bos = new BufferedOutputStream (fos);
        bos.write (data);
    }
    finally {
        if (bos != null) {
            try {
                bos.flush ();
                bos.close ();
            }
            catch (Exception e) {
            }
        }
    }
}

processImage

public static void processImage (File file, int rotationAngle, int compressionRatio) {

    BufferedOutputStream bos = null;

    try {

        Bitmap bmp = BitmapFactory.decodeFile (file.getPath ());

        Matrix matrix = new Matrix ();
        matrix.postRotate (rotationAngle);

        bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth (), bmp.getHeight (), matrix, true);

        FileOutputStream fos = new FileOutputStream (file);
        bmp.compress (Bitmap.CompressFormat.PNG, compressionRatio, fos);
    }
    catch (IOException e) {
        e.printStackTrace ();
    }
    catch (OutOfMemoryError t) {
        t.printStackTrace ();
    }
    catch (Throwable t) {
        t.printStackTrace ();
    }
    finally {
        if (bos != null) {
            try {
                bos.flush ();
                bos.close ();
            }
            catch (Exception e) {
            }
        }
    }
}

getCorrectCameraOrientation

    public static int getCorrectCameraOrientation (Activity activity, Camera.CameraInfo info) {

    int rotation = activity.getWindowManager ().getDefaultDisplay ().getRotation ();
    int degrees = 0;

    if (hasValidRotation (rotation)) {
        degrees = rotation * 90;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360;
    }
    else {
        result = (info.orientation - degrees + 360) % 360;
    }

    return result;
}
  • Actually i wanted image data on a particular angle from Camera. Actually i am receiving data from onPreviewFrame , from there i send that data to server for opponent and also render on my screen. I don't want any post processing. I want data in a same pattern. I don't know if it is possible or not. If possible it will be a great help for me – Md. Sulayman Apr 17 '17 at 10:33
  • It's not possible using Camera API, this is old API and is deprecated now. You can achieve this using Camera2 API, which is available for android 5+. Camera2 API is stable and easy to use. – Pehlaj - Mobile Apps Developer Apr 17 '17 at 10:35
  • :( I had to give support from 16. I will try camera2 for higher version but somehow I had to fix that issue. thanks for your reply. Can you give any suggestion so that I can reotate the byte before sending to server?? – Md. Sulayman Apr 17 '17 at 10:41
  • oh. I forgot to say thanks. Thank you for your reply – Md. Sulayman Apr 17 '17 at 10:41
  • First of all, apply the rotation as mentioned in the answer, which will give you same image which was captured, then upload same file to server. – Pehlaj - Mobile Apps Developer Apr 17 '17 at 10:56
1

Reason of problem: By default maximum devices return an image with 90 degree default orientation while using camera api 1. I am not sure about this in case of using camera api 2. But in case of Nexus 5x and some rare device (using camera api 1) , It return image with 270 degree default rotation which is an exceptional case on some specific model device. SO you have to add an addition rotation of 180 degree for Nexus 5X. Please check printing the log of image orientation of Nexus 5X.

Md. Sulayman
  • 551
  • 7
  • 20