Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Storage image gets rotated

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 ?

like image 469
firozaqiwu Avatar asked Mar 14 '18 12:03

firozaqiwu


1 Answers

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);
}
like image 115
Levon Petrosyan Avatar answered Sep 20 '22 13:09

Levon Petrosyan