Image is getting rotated when clicked from camera only in Samasung device - android

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.

Related

Can I get the orientation of a photo taken in my app if I limit the activity's orientation to portrait only in my manifest?

I don't want to support landscape UI at all across my app, but I want to be able to automatically rotate the photos users take in landscape mode.
Currently if a user takes a photo in landscape mode, it remains on screen as if it was taken in portrait (the horizon in the photo is vertical).
I've tried to get the orientation from the system like this:
val display = (getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
val screenOrientation = display.rotation
Log.d("orientation", screenOrientation.toString())
But it doesn't work and just gives back 0 every time.
I've tried a few other solutions but couldn't get them to work.
I am wondering, am I wasting my time trying to figure this out? Is it even possible to know the orientation in which the photo was captured if my activity only operates in portrait mode?
There are a few articles out there talking about camera orientation but they don't talk about whether the orientation in their activity is locked or not.
Thank you.
//Yes, find the Orientation Using ExifInterface
try{
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
// dont know exactly but, orientation for landscape may be 180 or 270.
// From the orientation value you can convert image according to orientation and can be set it vertically, horrizentally as below
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;
}
Log.e(Common.TAG, "Exif orientation: " + orientation);
}
catch (Exception e) {
e.printStackTrace();
}
// Now Change image as your wish...
// Image rotation //
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
Bitmap cropped = Bitmap.createBitmap(scaled, x, y, width, height, matrix, true);

Image rotated when taking a photo in portrait mode

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.

Android sending captured image rotates 90 degree in some devices

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;
}

Android image orientation issue with custom camera activity

I wrote a custom camera activity to handle some issues I've been having with certain android devices when calling intent image capture. The user is able to either select save image or just use the data returned back from the OnPictureTakenCallback.
The problem I'm having is displaying the image correctly with respect to the orientation it was taken. I force the activity to be displayed in portrait by calling SetRequestedOrientation.
How would I know the correct Orientation the camera was in when the user took the picture?
i.e. The user could take the picture at a rotation of 90 (portrait).
I've tried to get to use the getRotation() on the window manager's default display, but with setting the requested orientation to portrait that only returns Surface.ROTATION_0.
Update:
To clarify my other issue, how could I determine the orientation from just the byte[] data in the picture callback if the user were to not save the image?
Update: After trying the answers below with this code all I'm getting is ExifInterface.ORIENTATION_NORMAL. I've also changed my code to just save the file returned from the camera as I'm not sure there is an easy way to determine the orientation with just having the byte[] data.
private PictureCallback mPicture = new PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
File directory = new File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_PICTURES),
"MyApp");
if(!directory.exists())
{
if(!directory.mkdirs())
{
Log.d("CAMERA", "Unable to create directory to save photos.");
return;
}
}
File file = new File(directory.getPath() + file.separator + "IMG_" + SimpleDateFormat.getDateTimeInstance().toString() + ".jpg");
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
ExifInterface exif = new ExifInterface(file.getCanonicalPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
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;
case default:
break;
}
}
};
SO you are facing some issue with the orientation of the camera.
This link shows an example app of a simple camera capture activity :
http://labs.makemachine.net/2010/03/simple-android-photo-capture/
Maybe you should try fixing the orientation by doing something like this :
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
}
You will need to read the Metadata from the original JPEG to verify the orientation in which the picture was taken.
ExifInterface exif = new ExifInterface(SourceFileName);
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
Source: How to determine orientation of picture without ExifInterface?
Edit: Answering your edit, have you tried using the getCameraInfo() method that is available with the Camera object passed in the callback? Does it have the info you require?
Source: http://developer.android.com/reference/android/hardware/Camera.html
Removing the setRequestedOrientation() allowed getWindowManager().getDefaultDisplay().getRotation() to give the correct rotation. I guess setting the requested orientation prevents the activity from redrawing itself when the configuration changes thus the device doesn't know any kind of rotation changed. My only issue now is switching from landscape mode at 0 degrees orientation to landscape mode 180 degrees rotation does not fire this:
#Override
public void onConfigurationChanged(Configuration newconfig)
{
super.onConfigurationChanged(newconfig);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation !=
Configuration.ORIENTATION_LANDSCAPE)
{
parameters.set("orientation", "portrait"); <----THis gets the job done!!!
// For Android Version 2.2 and above
mCamera.setDisplayOrientation(90);
// For Android Version 2.0 and above
parameters.setRotation(90);
}
// End Effects for Android Version 2.0 and higher
mCamera.setParameters(parameters);
}
catch (IOException exception)
{
mCamera.release();
}
}

Picture orientation from gallery/camera intent [duplicate]

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

Categories

Resources