Images Taken with Action_Image_Capture Always Returns 1 for Exifinterface.Tag_Orientation on Some Gingerbread Devices

Images taken with ACTION_IMAGE_CAPTURE always returns 1 for ExifInterface.TAG_ORIENTATION on some Gingerbread devices

Ok guys, it seems like this bug for android won't be fixed for a while. Although I found a way to implement the ExifInformation so that both devices (ones with proper Exif tag, and also improper exif tags work together)..

So the issue is on some (newer) 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 I do is, i record the time when I'm starting the camera app from my app. THen on activity result, I query the Media Provider to see if any pictures were saved after this timestamp I saved. That means that, most likely OS saved the properly rotated picture in the default folder and of course put a entry in the media store and we can use the rotation information from this row. Now to make sure we are looking at the right image, i compare the size of this file to the one I have access to (saved in my own app folder);

    int rotation =-1;
long fileSize = new File(filePath).length();

Cursor mediaCursor = content.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] {MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.SIZE }, MediaStore.MediaColumns.DATE_ADDED + ">=?", new String[]{String.valueOf(captureTime/1000 - 1)}, MediaStore.MediaColumns.DATE_ADDED + " desc");

if (mediaCursor != null && captureTime != 0 && mediaCursor.getCount() !=0 ) {
while(mediaCursor.moveToNext()){
long size = mediaCursor.getLong(1);
//Extra check to make sure that we are getting the orientation from the proper file
if(size == fileSize){
rotation = mediaCursor.getInt(0);
break;
}
}
}

Now if the rotation at this point is still -1, then that means this is one of the phones with proper rotation information. At this point, we can use the regular exif orientation on the file that's returned to our onActivityResult

    else if(rotation == -1){
rotation = getExifOrientationAttribute(filePath);
}

You can easily find out how to find exif orientations like the answer in this question Camera orientation issue in Android

Also note that ExifInterface is only supported after Api level 5.. So if you want to support phones before 2.0, then you can use this handy library I found for java courtesy of Drew Noakes; http://www.drewnoakes.com/code/exif/

Good luck with your image rotating!

EDIT: Because it was asked, the intent I've used and how i started was like this

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//mediaFile is where the image will be saved
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
startActivityForResult(intent, 1);

EXIF orientation tag value always 0 for image taken with portrait camera app android

I also faced same issue in Samsung devices, later I implemented ExifInterface and solved successfully.

In any mode images will be shot it will always store in portrait mode only, and while fetching too returning in portrait mode. below of code I used to achieve my goal, I implemented within back camera, not sure about from camera.

Camera Intent@

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 1212);

onActivityResult@

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == 1212) {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Bitmap bitmap;
//bitmap=GlobalMethods.decodeSampledBitmapFromResource(_path, 80, 80);
bitmap=GlobalMethods.decodeFile(_path);
if (bitmap == null) {
imgMed.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.add_photo));
}
else {
imgMed.setImageBitmap(bitmap);
imgMed.setScaleType(ScaleType.FIT_XY);

}
}
}

decodeFile@

    public static Bitmap decodeFile(String path) {

int orientation;

try {

if(path==null){

return null;
}
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;

// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 4;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale++;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
Bitmap bm = BitmapFactory.decodeFile(path,o2);


Bitmap bitmap = bm;

ExifInterface exif = new ExifInterface(path);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
Log.e("orientation",""+orientation);
Matrix m=new Matrix();

if((orientation==3)){

m.postRotate(180);
m.postScale((float)bm.getWidth(), (float)bm.getHeight());

// if(m.preRotate(90)){
Log.e("in orientation",""+orientation);

bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true);
return bitmap;
}
else if(orientation==6){

m.postRotate(90);

Log.e("in orientation",""+orientation);

bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true);
return bitmap;
}

else if(orientation==8){

m.postRotate(270);

Log.e("in orientation",""+orientation);

bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true);
return bitmap;
}
return bitmap;
}
catch (Exception e) {
}
return null;
}

Exif data TAG_ORIENTATION always 0

My solution:

Remove any checking for orientation from exif data. I could not find one instance where it was accurate.

Use the standard String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION}; to get an orientation.

If this is 0 use
decodeStream...

if(o.outHeight > o.outWidth){
//set orientation to portrait
}

else it is landscape

Camera orientation issue in Android

There are quite a few similar topics and issues around here. Since you're not writing your own camera, I think it boils down to this:

some devices rotate the image before saving it, while others simply add the orientation tag in the photo's exif data.

I'd recommend checking the photo's exif data and looking particularly for

ExifInterface exif = new ExifInterface(SourceFileName);     //Since API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Since the photo is displaying correctly in your app, i'm not sure where the problem is, but this should definitely set you on the right path!



Related Topics



Leave a reply



Submit