Android image resizing and preserving EXIF data (orientation, rotation, etc.)

As far as I can tell, there is no mechanism to persist the metadata automatically or even snapshot whatever is there and transfer in bulk.

Rather, it seems you must explicitly check for specific properties and copy them yourself to the new image file using the ExifInterface.

http://developer.android.com/reference/android/media/ExifInterface.html

So something like:

ExifInterface oldExif = new ExifInterface(oldImagePath);
String exifOrientation = oldExif.getAttribute(ExifInterface.TAG_ORIENTATION);

if (exifOrientation != null) {
   ExifInterface newExif = new ExifInterface(imagePath);
   newExif.setAttribute(ExifInterface.TAG_ORIENTATION, exifOrientation);
   newExif.saveAttributes();
}

For the lazy ones, here’s a reusable function:

public static void copyExif(String oldPath, String newPath) throws IOException
{
    ExifInterface oldExif = new ExifInterface(oldPath);

    String[] attributes = new String[]
    {
            ExifInterface.TAG_APERTURE,
            ExifInterface.TAG_DATETIME,
            ExifInterface.TAG_DATETIME_DIGITIZED,
            ExifInterface.TAG_EXPOSURE_TIME,
            ExifInterface.TAG_FLASH,
            ExifInterface.TAG_FOCAL_LENGTH,
            ExifInterface.TAG_GPS_ALTITUDE,
            ExifInterface.TAG_GPS_ALTITUDE_REF,
            ExifInterface.TAG_GPS_DATESTAMP,
            ExifInterface.TAG_GPS_LATITUDE,
            ExifInterface.TAG_GPS_LATITUDE_REF,
            ExifInterface.TAG_GPS_LONGITUDE,
            ExifInterface.TAG_GPS_LONGITUDE_REF,
            ExifInterface.TAG_GPS_PROCESSING_METHOD,
            ExifInterface.TAG_GPS_TIMESTAMP,
            ExifInterface.TAG_IMAGE_LENGTH,
            ExifInterface.TAG_IMAGE_WIDTH,
            ExifInterface.TAG_ISO,
            ExifInterface.TAG_MAKE,
            ExifInterface.TAG_MODEL,
            ExifInterface.TAG_ORIENTATION,
            ExifInterface.TAG_SUBSEC_TIME,
            ExifInterface.TAG_SUBSEC_TIME_DIG,
            ExifInterface.TAG_SUBSEC_TIME_ORIG,
            ExifInterface.TAG_WHITE_BALANCE
    };

    ExifInterface newExif = new ExifInterface(newPath);
    for (int i = 0; i < attributes.length; i++)
    {
        String value = oldExif.getAttribute(attributes[i]);
        if (value != null)
            newExif.setAttribute(attributes[i], value);
    }
    newExif.saveAttributes();
}

As others have indicated, you must copy the Exif data from the original image to the final resized image. The Sanselan Android library is typically best for this. Depending on Android OS version, the ExifInterface sometimes corrupts the Exifdata.

In addition, the ExifInterface also handles a limited number of Exif tags — namely only the tags that it “knows” about. Sanselan on the other hand will keep all Exiftags and marker notes.

Here is a blog post that shows how to use Sanselan for copying image data:

Copying Exif metadata using Sanselan

BTW, on Android I also tend to rotate the images and remove the Orientation Exiftag. For example, on a Nexus S with Android 4.03, the camera was setting an orientation tag in the Exifmetadata, but the webview was ignoring that information and displaying the image incorrectly. Sadly, rotating the actual image data and removing the Exiforientation tag is the only way to get every program to display images correctly.