Search code examples
androidcamerarotationexif

How can I get the device orientation when a photo was taken


I've never been struggling this much with images as I am today and I'd appreciate some help :D
So, thing is, I'm using the built-in camera to capture a picture and then send it to the back end to save it but the orientation is messed up for Kit kat and specially Samsung devices. I tried to use the exif interface everyone suggests, but I just can't get the photo orientation.
A few minutes ago I found an answer somewhat related to this, saying that maybe a good solution is to save the device orientation when the picture is taken, which sounds pretty nice, however, I don't know how to do that with the built in camera, since I don't have full control when opening the camera with an Intent, like this:

mPathToTakenImage = ImageProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider",
            newFile);

    openCamera.putExtra(MediaStore.EXTRA_OUTPUT, mPathToTakenImage);
    openCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    startActivityForResult(openCamera, AlgebraNationConstants.TAKE_PHOTO_REQUEST_CODE);

So, how can I get the device orientation while the image was being taken in order to rotate the image correctly?
This is the code to rotate the image, however, I'm getting always zero:

        final Bitmap finalImg;
        final StringBuilder base64Image = new StringBuilder("data:image/jpeg;base64,");

        final ExifInterface exifInterface;

        try {
            final String imagePath = params[0].getPath();

            exifInterface = new ExifInterface(imagePath);

            final int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_UNDEFINED);

            final Bitmap takenPhoto = MediaStore.Images.Media.getBitmap(mRelatedContext.getContentResolver(),
                    params[0]);

            if (null == takenPhoto) {
                base64Image.setLength(0);
            } else {
                finalImg = rotateBitmap(takenPhoto, orientation);

                if (null == finalImg) {
                    base64Image.setLength(0);
                } else {
                    final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                    finalImg.compress(Bitmap.CompressFormat.JPEG, 75, byteArrayOutputStream);
                    final byte[] byteArray = byteArrayOutputStream.toByteArray();
                    base64Image.append(Base64.encodeToString(byteArray, Base64.DEFAULT));
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return base64Image.length() == 0 ? null : base64Image.toString();

I'm going crazy with this, any help will be deeply appreciated.

EDIT:
<code>exiftool</code> data from the picture I'm using, which is in landscape mode


Solution

  • So, I finally resolved my problem making use of these two answers:

    https://stackoverflow.com/a/17426328

    https://stackoverflow.com/a/40865982

    In general, the issue was due to the image allocation in disk since I don't know why Android didn't like the fact that I was giving my own path to save the taken image. At the end, the Intent to open the camera is looking like this:
    final Intent openCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(openCamera, AlgebraNationConstants.TAKE_PHOTO_REQUEST_CODE);

    And Android itself is resolving where to put the image. Nevertheless, @CommonsWare thanks for the enlightenment and answers.