javacoder123
javacoder123

Reputation: 193

Rotate image from uri address, using Picasso

I have successfully upload a Users profile image to the Firebase storage area under their UserID.

From there I have put the file path to that image in the Firebase database under the usersID

Firebase Database Structure, Showing he profileImage uri that is linked to the firebase storage area

When I am displaying the image on the page the image is rotated the wrong way around. The photo on my phone is portrait, but it is saving in the Firebase storage area as landscape.

Image Stored In Landscape orientation in Firebase Storage, but was taken in portrait orientation

The image rendered on my phone in the wrong orientation

What I want to be able to do is let the user select an image from the gallery, then display the image on a page.Then I want to be able to let the user rotate the image themselves, left or right using two buttons.

When I press the rotate buttons. The image successfully rotates once. Then when I press the Save Profile Image button it sends the original image from the gallery to the Firebase Storage area. It is storing and sending the wrong image to the Storage. Essentially, it is saving the original, unrotated image to the storage.

Is there a way that I can fix this?

Here is my code:

private FirebaseAuth auth;
private DatabaseReference myRef;
private FirebaseDatabase database;
private StorageReference storageReference;
private FirebaseUser user;

private ImageView profileImage;
private Uri imageUri;

private static final int GALLERY_INTENT = 2;

private ProgressDialog progressDialog;

/*
Skip irrelevant code
*/

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    {

        View view = inflater.inflate(R.layout.fragment_upload_image, container, false);

        // Creating firebase links etc
        database = FirebaseDatabase.getInstance();
        myRef = FirebaseDatabase.getInstance().getReference();
        auth = FirebaseAuth.getInstance();
        storageReference = FirebaseStorage.getInstance().getReference();
        user = auth.getCurrentUser();

        // Setting buttons
        profileImage = (ImageView) view.findViewById(R.id.imageViewProfileImage);
        ImageView rotateLeft = (ImageView) view.findViewById(R.id.imageRotateLeft);
        ImageView rotateRight = (ImageView) view.findViewById(R.id.imageRotateRight);
        Button uploadProfileImage = (Button) view.findViewById(R.id.buttonUploadProfileImage);
        Button saveProfileImage = (Button) view.findViewById(R.id.buttonSaveProfileImage);

        // Rotate Left is a button
        rotateLeft.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if(profileImage != null)
                {
                    // Rotate image 90
                    Picasso.get().load(imageUri).rotate(90).into(profileImage);
                }
            }
        });

        // Rotate Right is a button
        rotateRight.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if(profileImage != null)
                {
                    // Rotate image -90
                    Picasso.get().load(imageUri).rotate(-90).into(profileImage);
                }
            }
        });

        uploadProfileImage.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                // Send user to gallery
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType("image/*");
                startActivityForResult(intent, GALLERY_INTENT);
            }
        });

        // Save image to storage area
        saveProfileImage.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                progressDialog.setMessage("Uploading Image Please Wait...");
                progressDialog.show();

                final StorageReference filePath = storageReference.child("Images").child(user.getUid()).child(imageUri.getLastPathSegment());
                filePath.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
                {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
                    {
                        Toast.makeText(getActivity(), "Uploaded Successfully!", Toast.LENGTH_SHORT).show();
                        Uri downloadUri = taskSnapshot.getDownloadUrl();

                        // Save image uri in the Firebase database under the usersID
                        myRef.child("Users").child(user.getUid()).child("profileImage").setValue(downloadUri.toString());
                        progressDialog.dismiss();
                    }
                }).addOnFailureListener(new OnFailureListener()
                {
                    @Override
                    public void onFailure(@NonNull Exception e)
                    {
                        progressDialog.dismiss();
                        Toast.makeText(getActivity(), "Failed To Upload!", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

        return view;
    }

    // Get image data and display on page
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == GALLERY_INTENT && resultCode == RESULT_OK)
        {
            progressDialog = new ProgressDialog(getActivity());
            progressDialog.setMessage("Displaying Image...");
            progressDialog.show();

            imageUri = data.getData();
            Picasso.get().load(imageUri).into(profileImage);

            progressDialog.dismiss();
        }
    }

Upvotes: 0

Views: 1402

Answers (2)

first let see what is the problem. First of all, picaso open the image file and retrieve a bitmap from it. This bitmap is what is displayed into the imageView. When you rotate the image, what you are doing is rotating the bitmap, but the file with the original photo never change. So if you want to upload the rotate photo, you have to retrieve the new bitmap from the image view, create a new file with it and upload the new file.

That must do the trick.

Good luck

Upvotes: 0

Sergey Emeliyanov
Sergey Emeliyanov

Reputation: 6961

You can try downloading image as a Bitmap, then rotating it and then saving. Here is the code you can use to do that with Picasso:

int rotationAngle; // You set this angle before calling the method
Target target = new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        Matrix matrix = new Matrix();
        matrix.postRotate(rotationAngle);
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
                matrix, true);

        // Save the rotatedBitmap elsewhere
    }
    @Override
    public void onBitmapFailed(Drawable errorDrawable) {}
    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {}
};
void downloadImageRotateAndSave() {
    Picasso.with(getContext()).load(imageUri).into(target);
}

Upvotes: 1

Related Questions