Exif Orientation Tag Value Always 0 for Image Taken with Portrait Camera App Android

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

Android EXIF data always 0, how to change it?

Turns out my code was able to set the EXIF data, but there is a discrepancy between how Android interprets this data and how iOS and Chrome on a Mac (where I was checking the resulting file) interprets it.

This is the only code needed to set EXIF orientation:

ExifInterface exif = new ExifInterface(pictureFile.toString());
exif.setAttribute(ExifInterface.TAG_ORIENTATION, "3");
exif.saveAttributes();

However, setting 3 shows up as 0 on iOS and the image is sideways in Chrome.

setting 6 shows up as 3 on iOS and the image looks right in Chrome.

Android image selected from gallery Orientation is always 0 : Exif TAG

After you get Uri of selected Image call the below functions using this methods,

Like this,

Uri selectedImageUri = data.getData();
Bitmap bitmap = scaleImage(this,selectedImageUri);

The two functions to include in your activity are,

 public static Bitmap scaleImage(Context context, Uri photoUri) throws IOException {
InputStream is = context.getContentResolver().openInputStream(photoUri);
BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, dbo);
is.close();

int rotatedWidth, rotatedHeight;
int orientation = getOrientation(context, photoUri);

if (orientation == 90 || orientation == 270) {
rotatedWidth = dbo.outHeight;
rotatedHeight = dbo.outWidth;
} else {
rotatedWidth = dbo.outWidth;
rotatedHeight = dbo.outHeight;
}

Bitmap srcBitmap;
is = context.getContentResolver().openInputStream(photoUri);
if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
float maxRatio = Math.max(widthRatio, heightRatio);

// Create the bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = (int) maxRatio;
srcBitmap = BitmapFactory.decodeStream(is, null, options);
} else {
srcBitmap = BitmapFactory.decodeStream(is);
}
is.close();

/*
* if the orientation is not 0 (or -1, which means we don't know), we
* have to do a rotation.
*/
if (orientation > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);

srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
srcBitmap.getHeight(), matrix, true);
}

String type = context.getContentResolver().getType(photoUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (type.equals("image/png")) {
srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
} else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
byte[] bMapArray = baos.toByteArray();
baos.close();
return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
}

public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);

if (cursor.getCount() != 1) {
return -1;
}

cursor.moveToFirst();
return cursor.getInt(0);
}

To get Uri from File use this :

public static Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}

Q. Can you plz tell me what is "MAX_IMAGE_DIMENSION"? – Dhrupal Mar 13 '13
A. its based on your imageview size or the image size what you want to show.. whatever it is 60X60 then 60, 100X100 then 100 @Dhrupal

Using Android Camera API, snapped photo's orientation is always Undefined

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.

How to detect device rotation for setting EXIF orientation tag (Android)

Use the getRotation method:

Display display = ((WindowManager)
context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();

From the documentation:

Returns the rotation of the screen from its "natural" orientation. 
The returned value may be Surface.ROTATION_0 (no rotation), Surface.ROTATION_90, Surface.
ROTATION_180, or Surface.ROTATION_270.
For example, if a device has a naturally tall screen, and the user has turned it on its side to go into a landscape orientation, the value returned here may be either Surface.ROTATION_90 or Surface.ROTATION_270 depending on the direction it was turned.
The angle is the rotation of the drawn graphics on the screen, which is the opposite direction of the physical rotation of the device.
For example, if the device is rotated 90 degrees counter-clockwise, to compensate rendering will be rotated by 90 degrees clockwise and thus the returned value here will be Surface.ROTATION_90.

getRotation was introduced from Android 2.2. Use getOrientation if your target are older devices.

Got answer form here:
how to detect orientation of android device?

If you just want to detect orientation of the device then you can use an OrientationEventListener.

here's the official docs:
http://developer.android.com/reference/android/view/OrientationEventListener.html#onOrientationChanged(int)

But before you use anything, check out this excellent blog post about orientation handling in android:
http://android-developers.blogspot.in/2010/09/one-screen-turn-deserves-another.html



Related Topics



Leave a reply



Submit