i was following this link Android get Orientation of a camera Bitmap? And rotate back -90 degrees to rotate my image if/when necessary, but its not working for me, i get this error
05-28 23:29:30.049 9735-9735/ss.sealstudios.com.socialstories E/JHEAD: can't open '/document/508'
but checking it like below looks like there pointing in the right place
05-28 23:29:30.049 9735-9735/ss.sealstudios.com.socialstories I/System.out: bitmap uri content://com.android.providers.downloads.documents/document/508 0
//the 0 on the end is me checking for the rotation
i was wondering if this was build version specific like getting the real path from a URI as running this code on my marshmallow device gives me an entirely different result (this result, ie: error codes, is from a kitkat device), but this has defeated me for some weeks now following all sorts of answers to no avail, can anyone weigh in and help me please, here's what I'm trying to do
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data
!= null
&& data.getData() != null)
{
Uri uri = data.getData();
try {
BitmapFactory.Options bitmapOptions = new
BitmapFactory.Options();
bitmapOptions.inSampleSize = (int) 4;
InputStream inputStream =
getContentResolver().openInputStream(uri);
Bitmap scaledBitmap = BitmapFactory.decodeStream(inputStream,
null, bitmapOptions);
ExifInterface exif = new ExifInterface(uri.getPath());
int rotation =
exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
System.out.println("bitmap uri " + uri + " " + rotation);
Matrix matrix = new Matrix();
if (rotation != 0f){
matrix.preRotate(rotationInDegrees);
Bitmap.createBitmap(scaledBitmap, 0,
0,scaledBitmap.getWidth(),scaledBitmap.getHeight(),
matrix, true);
imageView.setImageBitmap(scaledBitmap);
}else
imageView.setImageBitmap(scaledBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
}
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180; }
else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270; }
return 0;
}
many thanks
ExifInterface exif = new ExifInterface(uri.getPath());
This will not work. If you call getPath() on a Uri, you are doing it wrong, as that is meaningless for most Uri values, particularly those with a content scheme, as your has.
Since the SDK's ExifInterface only works with local files, you will need other EXIF code. I use some code from the AOSP for this. That version of ExifInterface can work with an InputStream, so you can get a fresh InputStream for the content identified by the Uri and pass that to the alternative ExifInterface.
Related
I am using Samsung A52 to take some images with camera not my firebase app and save them, after that i would upload these images to firebase, iam compressing them before upload .
now after images were uploaded i checked and found that they are -90 rotated, not all images rotated , some were rotated and some weren't;
any idea?
or is there any possibly to detect while loading images from firebase if it rotated to retotate is to 90 ?
function to upload images after getting them from gallery.
for (uploadCount = 0; uploadCount < ImageList.size(); uploadCount++) {
String imagePath = productRef.child(UID).child("images").push().getKey();
Uri IndividualImage = ImageList.get(uploadCount);
assert imagePath != null;
StorageReference ImageName = productImagesRef.child(UID).child(imagePath);
//Compress Images
Bitmap bmp = null;
try {
bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), IndividualImage);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
assert bmp != null;
bmp.compress(Bitmap.CompressFormat.JPEG, 25, baos);
byte[] data = baos.toByteArray();
//End of compressing
//start on uploading compressed
ImageName.putBytes(data).addOnSuccessListener(taskSnapshot -> ImageName.getDownloadUrl()
.addOnSuccessListener(uri -> {
String url = String.valueOf(uri);
StoreLink(url, imagePath);
})).addOnProgressListener(snapshot1 -> {
double progress = (100.0* snapshot1.getBytesTransferred()/snapshot1.getTotalByteCount());
loadingDialog.setMessage("صورة رقم " + (count+ 1) + " -->> " +(int) progress + "%");
});
}
So i self Solved it and this was my solution:
i added a rotate button to the layout of recyclerView item(Adapter), and then created an empty ArrayList to store the value or rotation degree.
i passed the arraylist to adapter which has the rotate button, now when user click on rotate a value of 90f would be saved to arraylist with the position like this:
imageRotation.set(holder.getAdapterPosition(), "90f");
since arrayList can take (index, value)
Note: if there isn't an exiting value for the Arralist position and you skipped the position to change rotation for other item, it would crash.
and to solve this i made a for loop to populate the Arratlist with 0f as a rotatiion degree.
for (int i = 0; i <= imageUriList.size(); i++) {
imageRotation.add(i,"0f");
}
then when user click on rotate, it would update the position value:
imageRotation.set(holder.getAdapterPosition(), "90f");
and onActivityResult of the Upload Activity:
i used this:
if (requestCode == LAUNCH_SECOND_ACTIVITY) {
if (resultCode == Activity.RESULT_OK) {
assert data != null;
imageRotationArray = data.getStringArrayListExtra("imageRotationArray");
}
}
and before the Compress image function:
// create new matrix
Matrix matrix = new Matrix();
// setup rotation degree
matrix.postRotate(Float.parseFloat(imageRotationArray.get(countRotateImage)));
bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
countRotateImage++;
I use the camera api and the photo taken is always rotated by 90 degree, and i would like to rotate it.
So first of all i would like to know the picture's orientation and this point im stuck.
I always getting UNDEFINDED orientation in both ways.
Here is the code:
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//Bitmap Options for lowering quality the bitmap to save memory
Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
options.inPreferredConfig = Bitmap.Config.RGB_565;
//Make the bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
//Making the path, the root will be fine for tests
String path = Environment.getExternalStorageDirectory().toString();
//output stream
OutputStream outputStream = null;
//Making the file as a jpg
File file = new File(path, "tmp_pic" + ".jpg"); // the File to save to
try {
//Writing the file
outputStream = new FileOutputStream(file);
outputStream.flush();
outputStream.close(); // do not forget to close the stream
//Getting the orientation in both possible ways
int ori = getOrientationFromExif(file.getPath());
int ori2 = getOrientationFromUri(Uri.fromFile(file));
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
if (bitmap == null) {
Toast.makeText(getApplicationContext(), "Error: Cant make photo.", Toast.LENGTH_SHORT).show();
}
else {
PhotoTapView.photoViews.get(index).setPhotoImage(bitmap);
finish();
}
cameraObject.release();
}
The functions for orientation:
//Getting orientation from file URI
private int getOrientationFromUri(Uri imageUri) {
String[] orientationColumn = { MediaStore.Images.Media.ORIENTATION };
Cursor cur = getContentResolver().query(imageUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
Log.i("Orientation from Uri", orientation + "");
return orientation;
}
//Getting orientation from ExifInterface
private static int getOrientationFromExif(String imagePath) {
int orientation = -1;
try {
ExifInterface exif = new ExifInterface(imagePath);
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Log.i("Orientation from Exif: ", exifOrientation + "");
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
orientation = 270;
Log.i("Orientation from Exif", "270");
break;
case ExifInterface.ORIENTATION_ROTATE_180:
orientation = 180;
Log.i("Orientation from Exif", "180");
break;
case ExifInterface.ORIENTATION_ROTATE_90:
Log.i("Orientation from Exif", "90");
orientation = 90;
break;
case ExifInterface.ORIENTATION_NORMAL:
orientation = 0;
Log.i("Orientation from Exif", "0 - Normal");
break;
case ExifInterface.ORIENTATION_UNDEFINED:
orientation = -1;
Log.e("Orientation from Exif", "UNDEFINED");
}
}
catch (IOException e) {}
return orientation;
}
Log output:
01-14 19:46:09.468: E/Orientation from Exif(12411): UNDEFINED
01-14 19:46:09.468: I/Orientation from Uri(12411): -1
What could be the problem?
I have been decoding/observing Android JPEG images since early 2011 because I published an image viewing application. In the 'early' days, the images were encoded in the sensor's native orientation and the actual orientation of the device was written into the EXIF metadata. Starting about 2 years ago, I noticed that the orientation was no longer being written into the EXIF data and instead, the camera app was rotating the image pixels before encoding the JPEG files. My guess is that this occurred because some photo viewers (* cough * Windows * cough *) ignore the EXIF orientation when displaying JPEG files and instead of waiting for Microsoft to fix it and blaming Android for doing something wrong, they decided to make use of the faster CPU/memory and just rotate the image.
The result is that without knowing the EXIF orientation, one can only determine that a photo was captured in landscape or portrait orientation. This bit of info is only an assumption because the majority of camera sensors are wider than they are tall.
In this code
outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream); // Add this line
outputStream.flush();
outputStream.close(); // do not forget to close the stream
You forgot to actually write the bytes to the output stream. So, the file is 0 length and naturally doesn't contain any EXIF information.
Also be careful as you are calling decodeByteArray and then saving it out again, this will also lose the EXIF information! You need to parse the EXIF from the original image bytes.
Background
I need to rotate images taken by the camera so that they will always have a normal orientation.
for this, I use the next code (used this post to get the image orientation)
//<= get the angle of the image , and decode the image from the file
final Matrix matrix = new Matrix();
//<= prepare the matrix based on the EXIF data (based on https://gist.github.com/9re/1990019 )
final Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix,false);
bitmap.recycle();
fileOutputStream = new FileOutputStream(tempFilePath);
rotatedBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
rotatedBitmap.recycle();
here the compression rate (AKA "quality" parameter) is 100.
The problem
The code works fine, but the result is larger than the original, much much larger.
The original file is around 600-700 KB, while the resulting file is around 3MB ...
This is even though both the input file and the output file are of the same format (JPEG).
The camera settings are at "super fine" quality. not sure what it means, but I think it has something to do with the compression ratio.
What I've tried
I've tried to set the "filter" parameter to either false or true. both resulted in large files.
Even without the rotation itself (just decode and encode), I get much larger files sizes...
Only when I've set compression ratio to around 85, I get similar files sizes, but I wonder how the quality is affected compared to the original files.
The question
Why does it occur?
Is there a way to get the exact same size and quality of the input file ?
Will using the same compression rate as the original file make it happen? Is it even possible to get the compression rate of the original file?
What does it mean to have a 100% compression rate ?
EDIT: I've found this link talking about rotation of JPEG files without losing the quality and file size , but is there a solution for it on Android ?
Here's another link that says it's possible, but I couldn't find any library that allows rotation of jpeg files without losing their quality
I tried two methods but I found out those methods take too long in my case. I still share what I used.
Method 1: LLJTran for Android
Get the LLJTran from here:
https://github.com/bkhall/AndroidMediaUtil
The code:
public static boolean rotateJpegFileBaseOnExifWithLLJTran(File imageFile, File outFile){
try {
int operation = 0;
int degree = getExifRotateDegree(imageFile.getAbsolutePath());
//int degree = 90;
switch(degree){
case 90:operation = LLJTran.ROT_90;break;
case 180:operation = LLJTran.ROT_180;break;
case 270:operation = LLJTran.ROT_270;break;
}
if (operation == 0){
Log.d(TAG, "Image orientation is already correct");
return false;
}
OutputStream output = null;
LLJTran llj = null;
try {
// Transform image
llj = new LLJTran(imageFile);
llj.read(LLJTran.READ_ALL, false); //don't know why setting second param to true will throw exception...
llj.transform(operation, LLJTran.OPT_DEFAULTS
| LLJTran.OPT_XFORM_ORIENTATION);
// write out file
output = new BufferedOutputStream(new FileOutputStream(outFile));
llj.save(output, LLJTran.OPT_WRITE_ALL);
return true;
} catch(Exception e){
e.printStackTrace();
return false;
}finally {
if(output != null)output.close();
if(llj != null)llj.freeMemory();
}
} catch (Exception e) {
// Unable to rotate image based on EXIF data
e.printStackTrace();
return false;
}
}
public static int getExifRotateDegree(String imagePath){
try {
ExifInterface exif;
exif = new ExifInterface(imagePath);
String orientstring = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientstring != null ? Integer.parseInt(orientstring) : ExifInterface.ORIENTATION_NORMAL;
if(orientation == ExifInterface.ORIENTATION_ROTATE_90)
return 90;
if(orientation == ExifInterface.ORIENTATION_ROTATE_180)
return 180;
if(orientation == ExifInterface.ORIENTATION_ROTATE_270)
return 270;
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
Method 2: Using libjepg-turbo's jpegtran executable
1 Follow the step describe here:
https://stackoverflow.com/a/12296343/1099884
Except that you don't need obj/local/armeabi/libjpeg.a on ndk-build because I only want the jpegtran executable but not mess with JNI with libjepg.a .
2 Place the jpegtran executable on asset folder.
The code:
public static boolean rotateJpegFileBaseOnExifWithJpegTran(Context context, File imageFile, File outFile){
try {
int operation = 0;
int degree = getExifRotateDegree(imageFile.getAbsolutePath());
//int degree = 90;
String exe = prepareJpegTranExe(context);
//chmod ,otherwise premission denied
boolean ret = runCommand("chmod 777 "+exe);
if(ret == false){
Log.d(TAG, "chmod jpegTran failed");
return false;
}
//rotate the jpeg with jpegtran
ret = runCommand(exe+
" -rotate "+degree+" -outfile "+outFile.getAbsolutePath()+" "+imageFile.getAbsolutePath());
return ret;
} catch (Exception e) {
// Unable to rotate image based on EXIF data
e.printStackTrace();
return false;
}
}
public static String prepareJpegTranExe(Context context){
File exeDir = context.getDir("JpegTran", 0);
File exe = new File(exeDir, "jpegtran");
if(!exe.exists()){
try {
InputStream is = context.getAssets().open("jpegtran");
FileOutputStream os = new FileOutputStream(exe);
int bufferSize = 16384;
byte[] buffer = new byte[bufferSize];
int count;
while ((count=is.read(buffer, 0, bufferSize))!=-1) {
os.write(buffer, 0, count);
}
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return exe.getAbsolutePath();
}
public static boolean runCommand(String cmd){
try{
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
// Waits for the command to finish.
process.waitFor();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Unfortunately, both take too long. It is 16 seconds on my Samsung Galaxy S1!!!! But I found out this app (https://play.google.com/store/apps/details?id=com.lunohod.jpegtool) only take 3-4 seconds. There must be some way to do.
Once you are done setting you bestPreviewSize You have to now set for bestPictureSize every phone supports different picture sizes so to get Best Picture quality you have to check supported picture sizes and then set best size to camera parameter. You have to set those parameters in surface changed to get the width and height. surfaceChanged will be called in start and thus your new parameters will be set.
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters myParameters = camera.getParameters();
myPicSize = getBestPictureSize(width, height);
if (myBestSize != null && myPicSize != null) {
myParameters.setPictureSize(myPicSize.width, myPicSize.height);
myParameters.setJpegQuality(100);
camera.setParameters(myParameters);
Toast.makeText(getApplicationContext(),
"CHANGED:Best PICTURE SIZE:\n" +
String.valueOf(myPicSize.width) + " ::: " + String.valueOf(myPicSize.height),
Toast.LENGTH_LONG).show();
}
}
Now the getBestPictureSize ..
private Camera.Size getBestPictureSize(int width, int height)
{
Camera.Size result=null;
Camera.Parameters p = camera.getParameters();
for (Camera.Size size : p.getSupportedPictureSizes()) {
if (size.width>width || size.height>height) {
if (result==null) {
result=size;
} else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return result;
}
For rotation, try this..
final Matrix matrix = new Matrix();
matrix.setRotate(90):
final Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix,false);
I am using PNG images and it is working fine.... for JPEG images, please check the above code.
100% quality rate probably is a higher quality setting than the setting the files are originally saved with. This results in higher size but (almost) the same image.
I'm not sure how to get exactly the same size, maybe just setting the quality to 85% will do (Quick and Dirty).
However if you just want to rotate the pic in 90°-steps, you could edit just the JPEG-metadata without touching the pixel data itself.
Not sure how it's done in android, but this is how it works.
I'm testing my app on HTC Desire with Android 2.2. and it works exactly as I'd love to. I use Sherlock packages to have same style on older devices as on newer.
My AVD is set to use the latest android, and it also looks ok. Then I've placed it to Samsung Galaxy S2, and as I work with camera and gallery images, they are rotated wrong. It seams that something on Samsung (camera app, android it self) does not or it does check EXIF and my images are oriented wrong. Portrait images are loaded in landscape, and landscape images are loaded in portrait.
I guess I need to check EXIF somehow and ignore it in order to load images as they are?
Bigger problem is - how to know if there are any other devices (some HTC, some HUAWEI some whatsoever) that will do similar problem? I thought all android devices behave the same way beside having 4 screen size groups...
Tnx.
Without any code is hard to tell what's going on.
The most simple way i've found is to read the EXIF information and check if the image needs rotation. To read more on ExifInterface class on Android:
http://developer.android.com/intl/es/reference/android/media/ExifInterface.html
That said, here is some example code:
/** An URI and a imageView */
public void setBitmap(ImageView mImageView, String imageURI){
// Get the original bitmap dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(imageURI, options);
float rotation = rotationForImage(getActivity(), Uri.fromFile(new File(imageURI)));
if(rotation!=0){
//New rotation matrix
Matrix matrix = new Matrix();
matrix.preRotate(rotation);
mImageView.setImageBitmap(Bitmap.createBitmap(bitmap, 0, 0, reqHeight, reqWidth, matrix, true));
} else {
//No need to rotate
mImageView.setImageBitmap(BitmapFactory.decodeFile(imageURI, options));
}
}
/** Returns how much we have to rotate */
public static float rotationForImage(Context context, Uri uri) {
try{
if (uri.getScheme().equals("content")) {
//From the media gallery
String[] projection = { Images.ImageColumns.ORIENTATION };
Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
if (c.moveToFirst()) {
return c.getInt(0);
}
} else if (uri.getScheme().equals("file")) {
//From a file saved by the camera
ExifInterface exif = new ExifInterface(uri.getPath());
int rotation = (int) exifOrientationToDegrees(exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL));
return rotation;
}
return 0;
} catch (IOException e) {
Log.e(TAG, "Error checking exif", e);
return 0;
}
}
/** Get rotation in degrees */
private static float exifOrientationToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
If there is an error you will see the log "Error checking EXIF" on rotationForImage function.
This question already has answers here:
Images taken with ACTION_IMAGE_CAPTURE always returns 1 for ExifInterface.TAG_ORIENTATION on some Gingerbread devices
(5 answers)
Closed 4 years ago.
I'm getting picture to my app from camera / gallery intent. In many phones picture that I read from the intent / Uri is already rotated to correct orientation. For example N1, Legend, Desire that is the case.
But then on some phones ( for example Milestone1, GalaxyS) the picture is always in landscape more no matter which way the picture was taken. This means that in my application portrait picture is presented wrong way to the user. I tried to read EXIF info of the picture but orientation tag is always 0. There has to be a way to find out the right orientation of the picture because in Milestone1 the gallery application shows the portrait pictures correctly.
How do I know if I need to rotate the picture myself before showing it to the user?
Thank you for you help!
Florian answer is working for gallery images.
The following code works for captured images, havn't tried with gallery images but i believe it should work. Hope this helps anybody.
Code :
public static int getCameraPhotoOrientation(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.v(TAG, "Exif orientation: " + orientation);
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
EDIT:
As can be read in the comments, some devices do not support Exif information, havn't checked which but i think HTC doesn't. be sure to check what devices and create an alternative.
The following method returns the orientation of an image in degrees. It works with images from the gallery. Return values for:
normal landscape: 0
normal portrait: 90
upside-down landscape: 180
upside-down portrait: 270
image not found: -1
The code:
public static int getOrientation(Context context, Uri photoUri) {
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION },
null, null, null);
try {
if (cursor.moveToFirst()) {
return cursor.getInt(0);
} else {
return -1;
}
} finally {
cursor.close();
}
}
int rotate = 0;
try {
File imageFile = new File(sourcepath);
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;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
This is the best answer I have found, by ramaral. https://stackoverflow.com/a/20480741/2258389
Works great for gallery or camera
You have to create the gallery object using contentresolver first and then pass the uri created to the image capture intent. Then you can look at the exif data, NOT the gallery orientation data.
Matrix matrix = new Matrix();
ExifInterface exifReader = new ExifInterface(filePath);
int orientation = exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
if (orientation ==ExifInterface.ORIENTATION_NORMAL) {
// Do nothing. The original image is fine.
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
matrix.postRotate(90);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
matrix.postRotate(180);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
matrix.postRotate(270);
}
I have the same problem with S1, and I noted even if you open the image using stock gallery app it will open in landscape mode(the phone doesn’t know the correct orientation for photo).
And if you rotate the phone to portrait in camera app the icons (take pic, focus and settings) will not rotated, try that in S2 or any device support landscape/portrait camera those icons will be rotated.
What I am sure the stock camera app doesn’t support taking photos in prorate mode.
I already did that for a project, because I had the same problem (Android thinking you'll only do a picture on landscape). What I did was detecting the phone orientation at the time, and then rotate the image. It supposes the orientation is still the same when the intent is received, though.
This looks like the same problem that was solved in this question:
Android: Bitmaps loaded from gallery are rotated in ImageView
Use it this way!
private static int exifToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
And in the code,
Bitmap newImage = Bitmap.createBitmap(actualImage, 0, 0, width, height, matrix, true);
Simple!
What I am doing :
first check the orientation of image taken by camera using its meta data information , and If we found this in portrait then we have to rotate the image by 90 and display otherwise only display.
For getting the Information about orientation of image we can use Exif interface.
That's It!
The simple exiftodegree answers only consistently work when you have taken a photo and i use it for such. For those of you experiencing issues with choosing a photo and getting the correct orientation, see my answer here: Image Orientation - Android