In our app users have been uploading millions of images for years using (roughly) this code:
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(postFilePath, bmOptions);
Bitmap roughBitmap = BitmapFactory.decodeFile(postFilePath, bmOptions);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
roughBitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
InputStream fis = new ByteArrayInputStream(stream.toByteArray());
int fileSize = stream.toByteArray().length;
conn.setRequestProperty("Content-Length", Integer.toString(fileSize));
conn.setFixedLengthStreamingMode(fileSize);
...
if (fis != null) {
byte[] buf = new byte[10240];
int read;
while ((read = fis.read(buf)) > 0) {
os.write(buf, 0, read);
totalBytesRead += read;
if (uploadProgressListener != null) {
try {
uploadProgressListener.onBytesUploaded(read);
} catch (Exception e) {
Log.e(e);
}
}
}
fis.close();
}
Recently we saw the need to preserve the Exif
data of uploaded images. The problem is that the image Exif data is lost when compressing the bitmap. I thought of using ExifInterface
for extracting this data from the original file:
ExifInterface oldExif = new ExifInterface(postFilePath);
String value = oldExif.getAttribute(ExifInterface.TAG_DATETIME);
..and then adding it to the InputStream fis
and then continue uploading the file. The problem is that ExifInterface
cannot save Exif data to an InputStream.
How can Exif data be retained in the images when they'er uploaded to the server?
It's not a duplicate:
Just to clarify deeper, I've tried using the suggested duplicate question
by using this method:
public static void copyExif(String originalPath, InputStream newStream) throws IOException {
String[] attributes = new String[]
{
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_MAKE,
ExifInterface.TAG_MODEL,
ExifInterface.TAG_ORIENTATION,
ExifInterface.TAG_SUBSEC_TIME,
ExifInterface.TAG_WHITE_BALANCE
};
ExifInterface oldExif = new ExifInterface(originalPath);
ExifInterface newExif = new ExifInterface(newStream);
if (attributes.length > 0) {
for (int i = 0; i < attributes.length; i++) {
String value = oldExif.getAttribute(attributes[i]);
if (value != null)
newExif.setAttribute(attributes[i], value);
}
newExif.saveAttributes();
}
}
.. but got the exception java.io.IOException: ExifInterface does not support saving attributes for the current input.
after newExif.saveAttributes();
because I'm trying to save the attributes to an InputStream. How else can I do it?