0

In my code I allow user to upload photos from gallery or from camera. Then image is stored into the server through retrofit. When retrieved the photo is always rotated 90 degrees if the photo is taken using the phone's camera (regardless whether it is from invoked through the app or invoked through the camera directly). If the images are not taken using the camera, the orientation is correct. How do I resolve this?

I know if I tried to display the image directly without storing it in server, and it was possible to be in the right orientation because I could rotate it before displaying. I am doing something similar to the codes here: https://gist.github.com/Mariovc/f06e70ebe8ca52fbbbe2.

But because I need to upload to the server and then retrieve from the server again. How do I rotate it before storing to the server so that when I retrieve it, it is already in the right orientation?

Below is some parts of my codes (just some usual handling of images and displayAvatarInProfile() is called after the service finished the downloading of image):

public void displayAvatarInProfile(String filePath) {
    if(filePath != null && filePath != ""){
        int targetW = mProfilePicImageView.getWidth();
        int targetH = mProfilePicImageView.getHeight();
        Bitmap bm = ImageStorageUtils.resizePic(filePath, targetW, targetH);
        mProfilePicImageView.setImageBitmap(bm);
    } else {
        mProfilePicImageView.setImageBitmap(null);
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(resultCode == Activity.RESULT_OK) {
        Uri fileUri = null;
        String filePath = null;
        switch(requestCode) {
            case REQUEST_PICK_IMAGE: 
                fileUri = data.getData();
                break;
            case REQUEST_CAPTURE_IMAGE:
                File imageFile = ImageStorageUtils.getFile(
                        getActivity().getResources().getString(R.string.ApptTitle), 
                        "avatar_" + mUser.getLogin());
                filePath = imageFile.getAbsolutePath();
                fileUri = ImageStorageUtils.getUriFromFilePath(mContext.get(), filePath);
                break;
            default:
                break;
        }
        if(fileUri != null) {
            getActivity().startService(ProfileService.makeIntentUploadAvatar(
                    mContext.get(), mUser.getId(), fileUri));
        }
    }
  }


public void pickImage() {
    final Intent imageGalleryIntent = 
        new Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
            .setType("image/*")
            .putExtra(Intent.EXTRA_LOCAL_ONLY, true);

    // Verify the intent will resolve to an Activity.
    if (imageGalleryIntent.resolveActivity(getActivity().getPackageManager()) != null) 
        // Start an Activity to get the Image from the Image Gallery
        startActivityForResult(imageGalleryIntent,
            DisplayProfileFragment.REQUEST_PICK_IMAGE);

}

public void captureImage() {
    Uri captureImageUri = null;
    try {
        captureImageUri = Uri.fromFile(ImageStorageUtils.createImageFile(
                mContext.get(),
                getActivity().getResources().getString(R.string.ApptTitle), 
                "avatar_" + mUser.getLogin()));
    } catch (IOException e) {
        e.printStackTrace();
    }  

    // Create an intent that will start an Activity to get
    // capture an image.
    final Intent captureImageIntent =
            new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            .putExtra(MediaStore.EXTRA_OUTPUT, captureImageUri);

    // Verify the intent will resolve to an Activity.
    if (captureImageIntent.resolveActivity(getActivity().getPackageManager()) != null) 
        // Start an Activity to capture an image
        startActivityForResult(captureImageIntent,
            DisplayProfileFragment.REQUEST_CAPTURE_IMAGE);
}

Update 1

Was commented that I needed more description:

When I am uploading a file, I do this:

boolean succeeded = mImpatientServiceProxy.uploadAvatar(userId, new TypedFile("image/jpg", imageFile)); 

When I download, I get a retrofit.client.Response object, which I then get the InputStream from the Response and write the data to a file using an Output Stream.

final InputStream inputStream = response.getBody().in();
final OutputStream outputStream = new FileOutputStream(file);
IOUtils.copy(inputStream, outputStream);

Update 2

This is not a duplicate of existing solution because the user can upload from gallery, you do not know if it is a photo taken from resources online or from camera, so you cannot rotate the image when you display it.

halfer
  • 19,824
  • 17
  • 99
  • 186
yeeen
  • 4,911
  • 11
  • 52
  • 73
  • We cannot see what you upload. A file? A bitmap? Also we cannot see what you download and how. – greenapps Nov 02 '15 at 16:53
  • Hi @greenapps Please refer to my update above – yeeen Nov 03 '15 at 12:29
  • 1
    Possible duplicate of *[why image captured using camera intent gets rotated on some devices in android](http://stackoverflow.com/questions/14066038/why-image-captured-using-camera-intent-gets-rotated-on-some-devices-in-android)*. You should open the Jpeg file that you receive in `onActivityResult()`, rotate it as you wish, and compress it to Jpeg again. – Alex Cohn Nov 03 '15 at 17:05
  • Sorry but seeing one call i cannot see how it is done. – greenapps Nov 03 '15 at 17:13
  • @AlexCohn Oh... i think i didn't look at the page u sent carefully. Cos that time i thought it is not the same problem. Yes it works for me. But i have to use my own resize function for bitmap in additional to finding out its rotation from ExifInterface. Thanks! – yeeen Nov 05 '15 at 16:49
  • "Duplicate" is not a bad word, even though it appears next to other flags that point to low quality of the question. Actually quite often it requires experience and research to understand that two questions share the same root cause. – Alex Cohn Nov 05 '15 at 17:12

1 Answers1

0

Use camera api instead of intent. When you capture image using intents it displays rotated. In camera api there are methods by which you can change the rotation of the camera as well as the captured photo too.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • What do u mean by camera api instead of intent? Can u post some codes or links? Cos i searched online, camera api related codes also used intent – yeeen Nov 03 '15 at 12:25
  • www.tutorialspoint.com/android/android_camera.htm check out this one . You will understand everything what i was trying to say... – Developer_vaibhav Nov 03 '15 at 12:36
  • did u see the last example in that link . I think you have seen the very example in that link in he is using the intent just scroll down and see the last example in which he is showing the camera api – Developer_vaibhav Nov 03 '15 at 12:42
  • Yes realised is below. But... if i have to use intent, is there other ways? – yeeen Nov 03 '15 at 12:43
  • i don't think that there are other ways . Becoz once i also got stuck with this problem And then i solved this by using camera api. So its better if u use camera api becoz it has many functions by which u can achieve your task. – Developer_vaibhav Nov 03 '15 at 12:47
  • I believe you ignored my comment because it tags this question as duplicate. Please read carefully what is written there. – Alex Cohn Nov 05 '15 at 04:14