asqa
asqa

Reputation: 199

Portrait picture rotated 90 degree after upload to server

my apps have feature set photo profile, but when upload an image from gallery to server the image automatic rotated 90 degree, this issue appear only for portrait image, in landscape image running well, I already add crop feature but it doesn't help, here is my code to update profile image:

 private void updateProfile(){
    // multipart
    MultipartBody.Part _file = null;
    if(proPicPath != null){
        // ini progress listener
        ProgressRequestBody.ProgressListener progressListener = new ProgressRequestBody.ProgressListener() {
            @Override
            public void transferred(final int num, long transferred, long totalSize) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            dialogUpload.setMessage("Updating "+ num + "%");
                        }catch (NullPointerException ne){
                            ne.printStackTrace();
                        }
                    }
                });
            }
        };

        File file = new File(proPicPath);
        // init request body
        ProgressRequestBody requestFileBody = new ProgressRequestBody(file, "multipart/form-data", progressListener);
        _file = MultipartBody.Part.createFormData("caller_pic", file.getName(), requestFileBody);
    }

    // set request body
    RequestBody _caller_id = RequestBody.create(MediaType.parse("text/plain"), own.caller_id);
    RequestBody _name = null;
    if(!etUserName.getText().toString().isEmpty())
        _name = RequestBody.create(MediaType.parse("text/plain"), etUserName.getText().toString());
    RequestBody _email = null;
    if(!etUserEmail.getText().toString().isEmpty())
        _email = RequestBody.create(MediaType.parse("text/plain"), etUserEmail.getText().toString());

    Call<APIResponse<ContactItem>> call = ServicesFactory.getService().updateProfile(_caller_id, _name, _email, _file);
    call.enqueue(new Callback<APIResponse<ContactItem>>() {
        @Override
        public void onResponse(Call<APIResponse<ContactItem>> call, Response<APIResponse<ContactItem>> response) {
            dialogUpload.dismiss();
            dialogUpload = null;

            if(response.isSuccessful() && response.body().isSuccessful()){
                proPicPath = null;
                ContactItem updated = response.body().data;

                // save to session and update local variable
                own = SessionManager.saveProfile(ProfileActivity.this, updated);
                // update ui
                setUserInfo();
                checkProfileChanged();

                toast("Update profile success");
            }
            else{
                toast("Update profile failed");
            }
        }

        @Override
        public void onFailure(Call<APIResponse<ContactItem>> call, Throwable t) {
            dialogUpload.dismiss();
            dialogUpload = null;

            toast("Update profile failed");
        }
    });
}

Upvotes: 3

Views: 1117

Answers (1)

Vodet
Vodet

Reputation: 1519

I got exactly the same issue, I solve it with this :

int IMAGE_UPLOAD_MAX_COMPRESSION = 75;
Bitmap mSelectedImage;
                try {
                    mSelectedImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse("file:" + mCurrentPhotoPath));
                    mSelectedImage = PictureOrientation.bitmapFromUri(EditProfileActivity.this, Uri.parse("file:" + mCurrentPhotoPath));
                    OutputStream os = new FileOutputStream(mCurrentPhotoPath);
                    mSelectedImage.compress(Bitmap.CompressFormat.JPEG, IMAGE_UPLOAD_MAX_COMPRESSION, os);
                    os.flush();
                    os.close();

} catch (Exception ex) {
                    ex.printStackTrace();
                }

The interesting part for you is here

PictureOrientation.bitmapFromUri(EditProfileActivity.this, Uri.parse("file:" + mCurrentPhotoPath));

This is the PictureOrientation class :

public class PictureOrientation {

public static Bitmap bitmapFromUri(Context context, Uri photoUri)
        throws FileNotFoundException, IOException {
    InputStream is = context.getContentResolver().openInputStream(photoUri);
    BitmapFactory.Options dbo = new BitmapFactory.Options();
    dbo.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, dbo);
    is.close();

    int rotatedWidth, rotatedHeight;

    int orientation = 0;

    if (photoUri.toString().contains("content:/")) {
        orientation = getOrientation(context, photoUri);
    } else {
        int orientationFormExif = getOrientationFromExif(photoUri, context);
        orientation = decodeExifOrientation(orientationFormExif);
    }

    if (orientation == 90 || orientation == 270) {
        rotatedWidth = dbo.outHeight;
        rotatedHeight = dbo.outWidth;
    } else {
        rotatedWidth = dbo.outWidth;
        rotatedHeight = dbo.outHeight;
    }

    Bitmap srcBitmap = readScaledBitmapFromUri(photoUri, context,
            rotatedWidth, rotatedHeight);

    srcBitmap = setProperOrientation(orientation, srcBitmap);
    return srcBitmap;
}

private static int getOrientation(Context context, Uri photoUri) {
    /* it's on the external media. */
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[]{MediaStore.Images.ImageColumns.ORIENTATION},
            null, null, null);

    if (cursor.getCount() != 1) {
        return -1;
    }

    cursor.moveToFirst();
    return cursor.getInt(0);
}

private static int getOrientationFromExif(Uri imageUri, Context context) {
    int orientation = -1;
    File imageFile = new File(imageUri.getPath());
    try {
        ExifInterface exif;
        exif = new ExifInterface(imageFile.getAbsolutePath());
        orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return orientation;
}


private static int decodeExifOrientation(int orientation) {
    switch (orientation) {
        case ExifInterface.ORIENTATION_NORMAL:
            orientation = 0;
            break;
        case ExifInterface.ORIENTATION_ROTATE_90:
            orientation = 90;
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            orientation = 180;
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            orientation = 270;
            break;
        default:
            break;
    }
    return orientation;
}

private static Bitmap readScaledBitmapFromUri(Uri photoUri, Context context, int width, int height)
        throws FileNotFoundException, IOException {
    InputStream is;
    Bitmap srcBitmap;
    is = context.getContentResolver().openInputStream(photoUri);
    if (width > EditProfileActivity.IMAGE_WIDTH || height > EditProfileActivity.IMAGE_HEIGHT) {
        float ratio = calculateScaleRatio(width, height);
        srcBitmap = readRoughScaledBitmap(is, ratio);
        ratio = calculateScaleRatio(srcBitmap.getWidth(),
                srcBitmap.getHeight());
        srcBitmap = scaleBitmap(srcBitmap, ratio);
    } else {
        srcBitmap = BitmapFactory.decodeStream(is);
    }
    is.close();
    return srcBitmap;
}

private static float calculateScaleRatio(int width, int height) {
    float widthRatio = ((float) width) / ((float) EditProfileActivity.IMAGE_WIDTH);
    float heightRatio = ((float) height) / ((float) EditProfileActivity.IMAGE_HEIGHT);
    float maxRatio = Math.max(widthRatio, heightRatio);
    return maxRatio;
}

private static Bitmap readRoughScaledBitmap(InputStream is, float maxRatio) {
    Bitmap result;
    // Create the bitmap from file
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = (int) maxRatio;
    result = BitmapFactory.decodeStream(is, null, options);
    return result;
}

private static Bitmap scaleBitmap(Bitmap bitmap, float ratio) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();

    Matrix matrix = new Matrix();
    matrix.postScale(1f / ratio, 1f / ratio);

    Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, width, height,
            matrix, true);
    return result;
}

private static Bitmap setProperOrientation(int orientation, Bitmap srcBitmap) {
    if (orientation > 0) {
        Matrix matrix = new Matrix();
        matrix.postRotate(orientation);

        srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0,
                srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true);
    }
    return srcBitmap;
}
}

This class look the exif orientation of the picture and rotate it.

Upvotes: 2

Related Questions