pictures taken in vertical format are saved in landscape format and vice-versa. I am using Android camera by using this intent
Intent captureImage = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureImage.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(captureImage, CAMERA_PIC_REQUEST);
onActivityResult() I am just saving image URL to my database and displaying it in a listview.
but there orientatiuon changes. The same will happen if I choose image from gallery and save it.
I want the orientation in which photo has been taken. I dont want to change it. Is anybody have a solutin on this.
Some devices doesn't rotate image after it was taken but just write its orientation information into Exif data. So before using taken photo you should call method like :
private int resolveBitmapOrientation(File bitmapFile) throws IOException {
ExifInterface exif = null;
exif = new ExifInterface(bitmapFile.getAbsolutePath());
return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}
to check its orientation. Then apply:
private Bitmap applyOrientation(Bitmap bitmap, int orientation) {
int rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
default:
return bitmap;
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
and use this new bitmap in your listview. Or it's even better to call this methods just after your photo was taken and override it with new rotated one.
In case if you are receiving Bitmap data as Uri the following method can be used to retrieve its filepath:
public static String getPathFromURI(Context context, Uri contentUri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
DocumentsContract.isDocumentUri(context, contentUri)) {
return getPathForV19AndUp(context, contentUri);
} else {
return getPathForPreV19(context, contentUri);
}
}
private static String getPathForPreV19(Context context, Uri contentUri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
try {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(columnIndex);
} finally {
cursor.close();
}
}
return null;
}
#TargetApi(Build.VERSION_CODES.KITKAT)
private static String getPathForV19AndUp(Context context, Uri contentUri) {
String documentId = DocumentsContract.getDocumentId(contentUri);
String id = documentId.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);
if (cursor != null) {
try {
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
return cursor.getString(columnIndex);
}
} finally {
cursor.close();
}
}
return null;
}
You can also follow by this way:
static Uri image_uri;
static Bitmap taken_image=null;
image_uri=fileUri; // file where image has been saved
taken_image=BitmapFactory.decodeFile(image_uri.getPath());
try
{
ExifInterface exif = new ExifInterface(image_uri.getPath());
//Since API Level 5
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 270);
break;
case ExifInterface.ORIENTATION_NORMAL:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 0);
break;
}
}
catch (OutOfMemoryError e)
{
Toast.makeText(getActivity(),e+"\"memory exception occured\"",Toast.LENGTH_LONG).show();
}
public Bitmap RotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
round_Image = source;
round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
Related
I am facing a problem while capturing images using intent. The captured image is automatically rotated.
How to prevent the problem. Can someone help?
I hope my solution would still help,
byte[] data = null;
Bitmap bitmap = BitmapFactory.decodeByteArray(fileBytes, 0, fileBytes.length);
ByteArrayOutputStream outputStream = null;
try {
bitmap = ImageResizer.rotateImageIfRequired(bitmap, context, uri);
outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
data = outputStream.toByteArray();
} catch (IOException e) {
Timber.e(e.getMessage());
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
// Intentionally blank
}
}
return data;
}
public static Bitmap rotateImageIfRequired(Bitmap img, Context context, Uri selectedImage) throws IOException {
if (selectedImage.getScheme().equals("content")) {
String[] projection = { MediaStore.Images.ImageColumns.ORIENTATION };
Cursor c = context.getContentResolver().query(selectedImage, projection, null, null, null);
if (c.moveToFirst()) {
final int rotation = c.getInt(0);
c.close();
return rotateImage(img, rotation);
}
return img;
} else {
ExifInterface ei = new ExifInterface(selectedImage.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Timber.d("orientation: %s", orientation);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotateImage(img, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotateImage(img, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotateImage(img, 270);
default:
return img;
}
}
}
private static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
return rotatedImg;
}
In my app, am trying to let the user select an image from the phone storage and display it. Trying to do so, I've faced a problem that the image is returned rotated. So after some search I found some code snippets that helped me to do it right. But testing the same strategy on images selected from google drive or any cloud storage gives an error.
Here are the code snippets I use to get the absolute path and modify the image rotation.
private static String getRealPathFromURI(Context context, Uri uri) {
String filePath = "";
String wholeID = DocumentsContract.getDocumentId(uri);
Log.d("here", wholeID);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
Log.d("here", filePath);
return filePath;
}
public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
ExifInterface ei = new ExifInterface(image_absolute_path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotate(bitmap, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotate(bitmap, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotate(bitmap, 270);
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
return flip(bitmap, true, false);
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
return flip(bitmap, false, true);
default:
return bitmap;
}
}
public static Bitmap rotate(Bitmap bitmap, float degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
Matrix matrix = new Matrix();
matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
And finally am using the modify method here, after getting a bitmap:
public static String encodeImgToBase64(Uri uri, Context context) throws IOException {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
inputStream = context.getContentResolver().openInputStream(uri);
options.inSampleSize = calculateInSampleSize(options, REQUIRED_WIDTH, REQUIRED_HEIGHT);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(inputStream, null, options);
inputStream.close();
bitmap = modifyOrientation(bitmap, getRealPathFromURI(context, uri));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream);
byte[] imgByteArray = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
return Base64.encodeToString(imgByteArray, Base64.DEFAULT);
}
So, my question is how to do the same thing on images selected from a cloud storage ?
You can try download the image, save in device tmp storage then you can use same method that you used for gallery image to it.
I have been trying to save images to Firebase Storage but I noticed that almost all pictures saved from Gallery/Google Drive get rotated.(usually by 90 degrees)
Reading through older posts I realized that this is a common issue and I tried solving it by trying either solution from this post , or from this one , this one and I could go on.
After roughly 8 hours I finally decided to ask here. Is there a better and easier implementation to stop the images from getting rotated?
My last (and unsuccessful, obviously) implementation using ExifInterface (which returns all the time 0) is this one:
Selecting picture
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
OnActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContext().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
int rotateImageAngle = getPhotoOrientation(getContext(), selectedImage, filePath);
try {
bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), selectedImage);
// Log.d(TAG, String.valueOf(bitmap));
addPictureButton.setText("Done");
} catch (IOException e) {
e.printStackTrace();
}
if( bitmap != null)
{
RotateBitmap(bitmap , rotateImageAngle);
}
}
Helper methods
public int getPhotoOrientation(Context context, Uri imageUri, String imagePath){
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Log.i("RotateImage", "Exif orientation: " + orientation);
Log.i("RotateImage", "Rotate value: " + rotate);
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
public static Bitmap RotateBitmap(Bitmap source, int angle)
{
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
Note: If needed I will add the code that uploads images to Firebase
I have come to a solution thanks to this post.
I am going to post below a modified working version of the code for anybody that has this issue.
Fire up picture selection from gallery
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(intent, PICK_IMAGE_REQUEST);
OnActivityResult checking original roatation of the selected picture
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
// Get selected gallery image
Uri selectedPicture = data.getData();
// Get and resize profile image
String[] filePathColumn = {MediaStore.Images.Media.DATA};
// TRY getactvity() as well if not work
Cursor cursor = getContext().getContentResolver().query(selectedPicture, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
loadedBitmap = BitmapFactory.decodeFile(picturePath);
ExifInterface exif = null;
try {
File pictureFile = new File(picturePath);
exif = new ExifInterface(pictureFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
int orientation = ExifInterface.ORIENTATION_NORMAL;
if (exif != null)
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
loadedBitmap = rotateBitmap(loadedBitmap, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
loadedBitmap = rotateBitmap(loadedBitmap, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
loadedBitmap = rotateBitmap(loadedBitmap, 270);
break;
}
imageView.setImageBitmap(loadedBitmap);
}
}
RotateBitmap method
public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) {
Matrix matrix = new Matrix();
matrix.postRotate(degrees);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
I have been stuck in camera for 6 days but not getting any proper solution. When I am capturing image through camera intent, image is being rotated. I tried to fix the orientation but sometimes it's not giving bitmap value in onActivityResult(). It shows a black screen when I try to set image in ImageView. Here is my code Please help me -
//call intent to capture image
captureBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
try {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null)
{
startActivityForResult(takePictureIntent,AlletConstants.CAPTURE_RECEIPT_IMAGE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case AlletConstants.CAPTURE_RECEIPT_IMAGE:
if(data != null)
{
Uri qrcodeImageUri = data.getData();
bitmapReceiptImage = handleQrBarCodeImage(qrcodeImageUri);
mImageCaptureUri = AlletCommonUtility.bitmapToUri(getActivity(), bitmapReceiptImage);
doCrop();
AlletCommonUtility.showToast(getActivity(),"Uri = "+mImageCaptureUri);
}
break;
case AlletConstants.CROP_RECEIPT_FROM_CAMERA:
if(data != null)
{
Bundle qrcodeextras = data.getExtras();
if (qrcodeextras != null) {
Bitmap cropBitmap = qrcodeextras.getParcelable("data");
receiptImageView.setImageBitmap(cropBitmap);
bitmapReceiptImage = cropBitmap;
}
File qrcodeFile = new File(mImageCaptureUri.getPath());
if (qrcodeFile.exists())
qrcodeFile.delete();
}
break;
default:
break;
}
}
// use to get bitmap from uri
private Bitmap handleReceiptImage(Uri selectedImageUri)
{
String[] filePathColumn = {MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap bitmap = setCameraImageRotation(picturePath);
return bitmap;
}
private Bitmap setCameraImageRotation(String picturePath)
{
Bitmap bitmapQrBarImage = null;
try {
File f = new File(picturePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
AlletCommonUtility.showToast(getActivity(), "Orienattion = "+orientation);
Matrix mat = new Matrix();
mat.postRotate(getImageOrientation(orientation));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize= 4;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
bitmapQrBarImage = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
if (bitmapQrBarImage != null) {
AlletCommonUtility.showToast(getActivity(), "CAMERA_PIC_SELECTION = "+bitmapQrBarImage);
}
}
catch (IOException e) {
Log.w("TAG", "-- Error in setting image");
}
catch(OutOfMemoryError oom) {
Log.w("TAG", "-- OOM Error in setting image");
}
return bitmapQrBarImage;
}
// Use to crop image
private void doCrop() {
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size == 0) {
AlletCommonUtility.showToast(getActivity(), AlletMessage.NOT_CROP_IMAGE);
return;
} else {
intent.setData(mImageCaptureUri);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, AlletConstants.CROP_RECEIPT_FROM_CAMERA);
} else {
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = getActivity().getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
co.icon = getActivity().getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
co.appIntent= new Intent(intent);
co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(getActivity(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Choose Crop App");
builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dialog, int item ) {
startActivityForResult( cropOptions.get(item).appIntent, AlletConstants.CROP_RECEIPT_FROM_CAMERA);
}
});
builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
#Override
public void onCancel( DialogInterface dialog ) {
if (mImageCaptureUri != null ) {
getActivity().getContentResolver().delete(mImageCaptureUri, null, null );
mImageCaptureUri = null;
}
}
} );
AlertDialog alert = builder.create();
alert.show();
}
}
}
// use to rotate captured image from device camera
public static int getImageOrientation(int rotation)
{
int angle = 0;
switch (rotation) {
case 0:
angle = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
angle = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
angle = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
angle = 270;
break;
default:
break;
}
return angle;
}
I am getting image in landscape mode but not in potrait mode. Camera preview automatically rotates by 90 degrees after capturing image.
It is because of the image's EXIF data. You need to use a rotation method.
Depending on your build-in Camera orientation and orientation of device the pictures will have different rotations. You check the rotation of your particular image through ExifInterface.
/**
* #param filename Path to image file
* #param captureTime Time when image file was created
*/
public static int extractExifOrientationTagFromImageFile(String filename, long creationTime) {
/* The issue is on some devices, there's a bug that makes the picture taken saved in your app folder without proper
exif tags while a properly rotated image is saved in the android default folder (even though it shouldn't be).
Now what we do is recording the time when we're starting the camera app. Then we query
the Media Provider to see if any pictures were saved after this timestamp we've saved. That means most likely Android OS
saved the properly rotated picture in the default folder and of course put an entry in the media store and we can use the
rotation information from this row. */
int imageRotation = -1;
long imageFileSize = new File(filename).length();
Cursor mediaFileCursor = getContext().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.SIZE },
MediaStore.MediaColumns.DATE_ADDED + " >= ?", new String[] { String.valueOf(creationTime / 1000 - 1) },
MediaStore.MediaColumns.DATE_ADDED + " DESC");
if((mediaFileCursor != null) && (mediaFileCursor.getCount() != 0)) {
while(mediaFileCursor.moveToNext()) {
long mediaFileSize = getLongFromCursor(mediaFileCursor, MediaStore.MediaColumns.SIZE);
// Extra check to make sure that we are getting the orientation from the proper file
if(mediaFileSize == imageFileSize) {
imageRotation = getIntFromCursor(mediaFileCursor, MediaStore.Images.ImageColumns.ORIENTATION);
break;
}
}
}
/* Now if the rotation at this point is still -1, then that means this is one of the devices with proper rotation information. */
if(imageRotation == -1) {
ExifInterface exif = null;
try {
exif = new ExifInterface(filename);
}
catch (IOException e) {
e.printStackTrace();
}
imageRotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
}
return imageRotation;
}
private static final int COLUMN_NOT_EXISTS = -1;
public static Long getLongFromCursor(Cursor cursor, String columnName) {
int columnIndex;
if((columnIndex = cursor.getColumnIndex(columnName)) != COLUMN_NOT_EXISTS) {
return cursor.getLong(columnIndex);
}
else {
return null;
}
}
public static Integer getIntFromCursor(Cursor cursor, String columnName) {
int columnIndex;
if((columnIndex = cursor.getColumnIndex(columnName)) != COLUMN_NOT_EXISTS) {
return cursor.getInt(columnIndex);
}
else {
return null;
}
}
Now when you have your image rotation you can rotate it's bitmap properly:
int imageRotation = extractExifOrientationTagFromImageFile(lastCapturedMediaUriPath, cameraAppInvokeTime);
Matrix matrix = new Matrix();
switch(imageRotation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
break;
default:
break;
}
final Bitmap loadedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
How to pick an image from gallery (SD Card) for my app?
I have implemented the second answer (With the downsampling). When I select an image in portrait, the image will be shown in landscape mode.. Does anybody know why this is? And how to fix this? Thanks in advance!
P.s. Sorry I've made a new topic out of this but the poster protected his topic against newbies like me :)
You have to get the exif rotation of the pic, like this and arrange youur bitmap accordingly
public static int getExifRotation(String imgPath)
{
try
{
ExifInterface exif = new ExifInterface(imgPath);
String rotationAmount = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
if (!TextUtils.isEmpty(rotationAmount))
{
int rotationParam = Integer.parseInt(rotationAmount);
switch (rotationParam)
{
case ExifInterface.ORIENTATION_NORMAL:
return 0;
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
}
else
{
return 0;
}
}
catch (Exception ex)
{
return 0;
}
}
get the path of the picture
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Thin make a matrix and use bitmap constructor that uses matrix
Matrix matrix = new Matrix();
matrix.preRotate(90);
// or
matrix.postRotate(90);
so inside your onActivityResult you should have something like this
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
orientation = getExifRotation(selectedImagePath);
Matrix matrix = new Matrix();
matrix.postRotate(90);
if(orientation == 90){
bitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(),
matrix, true);}
make sure you resample your image first though, so how he has it in his answer first and then do this