How to attach EXIF metadata to a serialized Bitmap in Android?

Warlax picture Warlax · Jan 26, 2011 · Viewed 8.8k times · Source

In Android, when decoding a Bitmap from a photo on the phone, the EXIF data in the original gets lost. I am sending this Bitmap to my server via a socket and would like to re-attach the missing EXIF data to the data being sent.

I have some code that loads a Bitmap object from the MediaStore and compresses it to a byte array in preparation to send it over a socket:

Bitmap bitmap = ...
ByteArrayOutputStream stream = new ByteArrayOutputStream(bitmap);
bitmap.compress(CompressFormat.JPEG, 70, stream);
byte[] input = stream.toByteArray();

I want to use the ExifInterface to get at the EXIF metadata in the original jpeg on the SD card and somehow add that to the outgoing byte array in a way that I'd be able to extract a jpeg with all the correct EXIF on the server side (hopefully without doing this on the server). So far, I managed to use the ExifInterface to read all EXIF data:

String path = ... //bitmap file path
ExifInterface exif = new ExifInterface(path);
... = exif.getAttribute(...)

EDIT: Optimally, I'd like to find a solution that uses no libraries. If I could just get the indices of the byte array of the original jpeg that contain the EXIF and prepend/append these bytes to the byte array produced by bitmap.compress(...) that would be best.

Answer

Vikas picture Vikas · May 11, 2011

Thanks to @Nick Campion and Sanselan.

Working code:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, bos); //Bitmap object is your image
byte[] data = bos.toByteArray();

TiffOutputSet outputSet = null;

IImageMetadata metadata = Sanselan.getMetadata(new File(filepath)); // filepath is the path to your image file stored in SD card (which contains exif info)
JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
if (null != jpegMetadata)
{
    TiffImageMetadata exif = jpegMetadata.getExif();
    if (null != exif)
    {
        outputSet = exif.getOutputSet();
    }
}
if (null != outputSet)
{
    bos.flush();
    bos.close();
    bos = new ByteArrayOutputStream();
    ExifRewriter ER = new ExifRewriter();
    ER.updateExifMetadataLossless(data, bos, outputSet);
    data = bos.toByteArray(); //Update you Byte array, Now it contains exif information!
}