I found the below code from the answer of @Haresh Chhelana and modified it a little, in order to rotate the photo chose from gallery OR taken by the camera using Android mobile phone, before saving it to Parse cloud.
When I take a picture from camera, with landscape or portrait orientation, it is always looking correct as I checked it from Parse.
When I choose a landscape photo from gallery the photo is being saved correctly again.
BUT, when I try to save a portrait photo, the photo is being saved landscape.
Note that in my manifest I have those lines, so that my application always run in portrait orientation (I don't know if this has something to do with the problem):
android:configChanges="orientation"
android:screenOrientation="portrait"
Those are the listeners for the buttons that the user press when he wants to upload a picture from gallery or take a new picture:
picture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, ""), PICK_IMAGE);
flag_photo = true;
}
});
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
startActivityForResult(intent, CAPTURE_IMAGE);
}
});
The way I save the photo in one of my functions:
ParseFile file = null;
file = new ParseFile("profile_picture.jpg", image);
// Upload the image into Parse Cloud
file.saveInBackground();
user.put("photo", file);
The OnActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CAPTURE_IMAGE) {
rotateImage(getImagePath());
} else if (requestCode == PICK_IMAGE) {
// imgFromCameraOrGallery.setImageBitmap(BitmapFactory.decodeFile(getAbsolutePath(data.getData())));
// Convert it to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Compress image to lower quality scale 1 - 100
BitmapFactory.decodeFile(getAbsolutePath(data.getData())).compress(Bitmap.CompressFormat.JPEG, 100, stream);
image = stream.toByteArray();
}
flag_photo = true;
}
else
flag_photo = false;
}
The RotateImage function :
private void rotateImage(final String path) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Bitmap b = decodeFileFromPath(path);
try {
ExifInterface ei = new ExifInterface(path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
break;
default:
b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
break;
}
} catch (Throwable e) {
e.printStackTrace();
}
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", "image" + new Date().getTime() + ".jpg");
}
else {
file = new File(getFilesDir() , "image" + new Date().getTime() + ".jpg");
}
out1 = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.JPEG, 100, out1);
// Convert it to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
BitmapFactory.decodeFile(file.getAbsolutePath()).compress(Bitmap.CompressFormat.JPEG, 100, stream);
// Compress image to lower quality scale 1 - 100
image = stream.toByteArray();
//imgFromCameraOrGallery.setImageBitmap(BitmapFactory.decodeFile(file.getAbsolutePath()));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out1.close();
} catch (Throwable ignore) {
}
}
}
});
}
And this is the DecodeFileFromPath:
private Bitmap decodeFileFromPath(String path){
Uri uri = getImageUri(path);
InputStream in = null;
try {
in = getContentResolver().openInputStream(uri);
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
int inSampleSize = 1024;
if (o.outHeight > inSampleSize || o.outWidth > inSampleSize) {
scale = (int) Math.pow(2, (int) Math.round(Math.log(inSampleSize / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
in = getContentResolver().openInputStream(uri);
Bitmap b = BitmapFactory.decodeStream(in, null, o2);
in.close();
return b;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
I also have those functions if you want to see their code. I haven't post them because my question became too long and I don't believe that I can change something in them to solve my problem: