Firebase Storage image gets rotated
Asked Answered
C

1

10

In my app I prompt the user to capture an image. The users camera activity starts on a buttonClick and the user gets the option to use the camera to capture an image.

This image saves on the users phone. The image is then uploaded to firebase Storage and all is working good. Feedback from one user, using a Samsung Note 8, is that when the image is captured in portrait mode, he later in the app gets it displayed in landscape mode.

I looked in the firebase storage and found that the image is saved in the storage in LANDSCAPE mode, even though the user captured the image in portrait mode.

I guess I have to pass meta data to the jpeg file that the image is captured in portrait mode, for firebase to know that it actually IS portrait mode.

This is the code for capturing image:

private void takePhoto() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        try {


            photoFile = createImageFile();


        } catch (IOException ex) {
            // Error occurred while creating the File

        }


        if (photoFile != null) {


            imageUri = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);

        }
    }
}

This is the method CreateImageFile:

public File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyy.MM.dd_HH:mm:ss").format(new Date());

    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "MAP_NAME");

    if (!storageDir.exists()) {
    if (!storageDir.mkdir()) {
        return null;
    }

}

    File image = File.createTempFile(
            imageFileName,
            ".jpg",
            storageDir
    );


    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();
    return image;


}

And Finally the code for uploading the code for uploading the image to firebase Storage:

private StorageTask mUploadTask;

private void uploadFile() {
    final String dateStamp = new SimpleDateFormat("dd MM").format(new Date());
    final String timeStamp = new SimpleDateFormat("HH:mm:ss").format(new Date());

    if (mImageUri != null) {
        StorageReference fileReference = mStorageRef.child(System.currentTimeMillis() + "");

        mUploadTask = fileReference.putFile(mImageUri)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

                        Handler handler = new Handler();
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                mProgressBar.setProgress(0);
                            }
                        }, 500);

When later displaying the image from the firebase storage, I use the picasso library like this:

Picasso.with(mContext)
            .load(uploadCurrent.getImageUrl())
            .placeholder(R.mipmap.ic_launcher)
            .centerCrop()
            .fit()
            .into(holder.imageView);

Is it possible to detect the rotation with help from picasso ?

Constant answered 14/3, 2018 at 12:32 Comment(7)
Possible duplicate of Android : How to detect the image orientation (portrait or landscape) picked from gallery while setting on an imageview?Eserine
I am later in my code retrieving the image from firebase storage to a recyclerview - cardview. How can I detect if the image is rotated or not when it is rotated in the firebase storage ?Constant
you need to implement Exif Interface and change orientation of image taken from camera/gallery before uploading to firebase storage, follow this answerHeiskell
You determine and correct the orientation of the image while you upload it to firebase storage. It has to come back the same way it was uploaded.Eserine
I have read it, but is it possible to get atleast a hint where to start implementing the EXIF in my code ? I would like to add, that I am trying to work with fullSize images, and not bitmaps.Constant
Same issue. Interesting seeing that on imgur, Google Drive, or any other service, it appears upright. Have you found anything? Exif orientation also seems fine...Afrikaner
Not found any further info that helps to resolve the issue.. Solved with the workaround, I allow the users to set default orientation mode for the images. If the user takes an image in portrait mode, and it displays in landscape, I provide the possibility to rotate this image so it is correctly rotated.Constant
H
6

I had the same issue while using google example for taking photo and the thing is that after capturing when I am setting the path to imageView by Glide it's displaying in correct orientation but after upload it got rotated in Firebase Storage.

So in onActivityResult I am setting the path to imageView, then getting Bitmap from the path, rotating it and save it back to the path, and after that uploading the file to Firebase Storage.

private Disposable disposable;

disposable = Completable
     .fromAction(this::handleImageOrientation)
     .subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .subscribe(this::uploadProfilePic);

@Override
public void onDestroy() {
    super.onDestroy();
    if (disposable != null) {
        disposable.dispose();
        disposable = null;
    }
}

If you are not using RxRava

new Thread() {
     @Override
     public void run() {
         super.run();
         handleImageOrientation();
         getActivity().runOnUiThread(() -> uploadProfilePic());
     }
}.start();

I am using android.support.media.ExifInterface from the support library, hence android.media.ExifInterface implementation has some known security bugs in older versions of Android.

build.gradle

implementation "com.android.support:exifinterface:27.1.1"

handleImageOrientation()

private void handleImageOrientation() {
        Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath);
        Bitmap rotatedBitmap;
        try {
            ExifInterface ei = new ExifInterface(currentPhotoPath);
            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);

            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotatedBitmap = Utils.rotateImage(bitmap, 90);
                    break;

                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotatedBitmap = Utils.rotateImage(bitmap, 180);
                    break;

                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotatedBitmap = Utils.rotateImage(bitmap, 270);
                    break;

                case ExifInterface.ORIENTATION_NORMAL:
                default:
                    rotatedBitmap = bitmap;
            }
         if (rotatedBitmap != bitmap) {
            FileOutputStream fOut = new FileOutputStream(currentPhotoPath);
            rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
            fOut.close();
        }
            bitmap.recycle();
            rotatedBitmap.recycle();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Utils.rotateImage()

public static Bitmap rotateImage(Bitmap source, float angle) {
     Matrix matrix = new Matrix();
     matrix.postRotate(angle);
     return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
Hollowell answered 19/8, 2018 at 9:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.