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 ?
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With