I am working on an Android application. In my app I have to capture a image and send that image to server. In some device the captured image posted in server with 90 degree rotation. I searched in stackoverflow and some other sites for a fix. I got solutions ..I used all them For eg:
Uri selectedImage = data.getData();
File imageFile = new File(selectedImage.toString());
ExifInterface exif;
try {
exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate=90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate=180;
break;
}
But unfortunately I am getting orientation 0 always in every device. Even in the 90 degree rotated image devices.
Please help to fix my issue friends.
You use:
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
So, you send defaultValue ExifInterface.ORIENTATION_NORMAL. Maybe your exif hasn't attribute TAG_ORIENTATION (or ORIENTATION_UNDEFINED) and you get default value?
Try:
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
and see what you get.
I fixed my issue by using the following code.
private int getImageOrientation(){
final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION };
final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
imageColumns, null, null, imageOrderBy);
if(cursor.moveToFirst()){
int orientation = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION));
rotate=orientation;
System.out.println("orientation==="+orientation);
cursor.close();
return orientation;
} else {
return 0;
}
}
Thanks for your response dear friends...
Please check if your images are rotated at 270 degrees
add this to your switch statement
switch(orientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
rotate=90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate=180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate=270;
break;
}
Related
In my application Image is getting rotated when it is clicked from camera in portrait mode, this happens only for samsung device and for the rest it works fine. I implemented following code after researching in stack overflow:
ExifInterface ei = new ExifInterface(imgFile.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
switch (orientation) {
case ExifInterface.ORIENTATION_UNDEFINED:
mBitmap = rotateImage(bitmap, 90);
break;
}
This code helps me to fix that issue in samsung but now when image is clicked from camera it is getting rotated in other devices due to this piece of code.
Please let me know how can I fix this issue.
pass that return degrees to convert the bitmap,
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;
}
If you are confident that this is only Samsung device issue, you can check for the device make and add that to your if(...) condition. This library can be of great help.
Also have a look at Jared Rummler's answer to this question:
But if this is a device specific issue, it may occur on other devices too or may be eventually corrected in newer Samsung device OS updates. Keep a good check on that.
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.
I'm trying to identify the orientation of the image using:
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
I'm not sure if it's working correctly. Here's why:
I take an image of a paper on my desk with "Portrait" orientation. My phone is in a plane parallel to the desk. However, the phone saves the image, rotated counter-clockwise 90 degrees.
I don't know why it does that, but regardless, I expect my exifOrientation to be 6, so that I could use this to rotate my image:
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
...
...
}
However, my exifOrientation is 1 and the image does not get correctly rotated.
I have looked at :
Why does an image captured using camera intent gets rotated on some devices on Android?
and even tried:
private int getImageOrientation(){
final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION };
final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
imageColumns, null, null, imageOrderBy);
if(cursor.moveToFirst()){
int orientation = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION));
cursor.close();
return orientation;
} else {
return 0;
}
}
To reiterate, I'm trying to identify the correct orientation.
I have implemented a custom camera from which I take a picture,save it insert it into the media store and display it immediately after.I have been plagued by the problem of the saved image orientation,I have tried to fix this using ExifInterface using the filePath directly or by using the orientation from the Android Images content provider.
The orientation is always returned as 0.I have already used:
Android image selected from gallery Orientation is always 0 : Exif TAG
private int getExifOrientation(String pathName)
{
//for complete info on EXIF orientation visit: http://sylvana.net/jpegcrop/exif_orientation.html
ExifInterface exif=null;
try {
exif = new ExifInterface(pathName);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("ImagePreviewActivity", "Exif data of the image could not be retreived");
}
int orientation=exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
return orientation;
}
private int getRotation(int orientation)
{
int rotation=0;
switch(orientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
//orientation values is 6
rotation=90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
//orientation value is 3
rotation=180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
//orientation value is 8
rotation=270;
break;
case -1:
Log.d("ImagePreviewActivity","Error getting orientation from Exif data.");
break;
case 1:
Log.d("ImagePreviewActivity", "Image is properly oriented");
default:
Log.d("ImagePreviewActivity", "The value of orientation is "+orientation);
}
return rotation;
}
private Bitmap rotateBitmap(String pathName,int rotation)
{
Bitmap bmp=BitmapFactory.decodeFile(pathName);
Matrix matrix=new Matrix();
matrix.postRotate(90);
//start from x=0,y=0 and filter=false
Bitmap rotatedBitmap=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,false);
return rotatedBitmap;
}
EDIT:
The output image has been displaying correctly when I take the picture in the Landscape mode,however it returns a rotated image(90 degrees) when taking a picture in portrait mode.
I am currently using the EXIF based method.
Make sure the pathname you are passing in does not have "file://" at the beginning of it. ExifInterface doesn't throw an error or anything if your path is prefixed with that, it just returns default for the orientation every time.
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