Cbas Cbas - 2 months ago 25
Android Question

Android EXIF data always 0, how to change it?

I have an app that captures photos using the native

Camera
and then uploads them to a server. My problem is that all the photos have an EXIF orientation value of 0, and this messes up the display elsewhere.

How can I change the EXIF orientation? I'm not looking for a way to correct it for every circumstance, just change it to a different value.

I'm using a Samsung Galaxy Note 4

I tried this solution that sets the camera orientation before taking photos: Setting Android Photo EXIF Orientation

Camera c = Camera.open();
c.setDisplayOrientation(90);

Camera.Parameters params = mCamera.getParameters();
params.setRotation(0); // tried 0, 90, 180
c.setParameters(params);


but it doesn't influence the resulting EXIF data, its still always 0

I also tried these solutions where the image is rotated after it is taken: EXIF orientation tag value always 0 for image taken with portrait camera app android

and while this rotates the photo, the EXIF orientation is still always 0.

I also tried setting the EXIF data directly: How to save Exif data after bitmap compression in Android

private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
final File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE, "");
try {
FileOutputStream fos = new FileOutputStream(pictureFile);

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

fos.write(data);
fos.close();

//upload photo..
}
}
}


but EXIF Orientation is still 0 after uploading.

I have also looked at these solutions:

Exif data TAG_ORIENTATION always 0

How to write exif data to image in Android?

How to get the Correct orientation of the image selected from the Default Image gallery

how to set camera Image orientation?

but they all involve correcting the orientation by rotating, which doesn't influence the EXIF data, or setting the EXIF data directly which doesn't seem to work.

How can I change the file's EXIF orientation data from 0 to 3?

UPDATE:

here is my upload code:

Bitmap sBitmap = null;
final File sResizedFile = getOutputMediaFile(MEDIA_TYPE_IMAGE, "_2");
try {
sBitmap = BitmapFactory.decodeStream(new FileInputStream(pictureFile), null, options);
} catch (FileNotFoundException e) {
Log.e("App", "[MainActivity] unable to convert pictureFile to bitmap");
e.printStackTrace();
return;
}

// ... compute sw and sh int values

Bitmap sOut = Bitmap.createScaledBitmap(sBitmap, sw, sh, false);
Bitmap rotatedBitmap = rotateBitmap(sOut, 3);
FileOutputStream sfOut;
try {
sfOut = new FileOutputStream(sResizedFile);
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 70, sfOut);
sfOut.flush();
sfOut.close();
sBitmap.recycle();
sOut.recycle();
rotatedBitmap.recycle();
} catch (Exception e) {
Log.e("App", "[MainActivity] unable to save thumbnail");
e.printStackTrace();
return;
}
// upload small thumbnail
TransferObserver sObserver = transferUtility.upload(
"stills/small", /* The bucket to upload to */
filename + ".jpg", /* The key for the uploaded object */
sResizedFile /* The file where the data to upload exists */
);

Answer

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 (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.