feat(android): write Exif tags to modified image file (#2263)

This commit is contained in:
Valentin 2019-05-15 15:10:03 +03:00 committed by Sibelius Seraphini
parent 481594c4c6
commit 8ad809ee88
4 changed files with 56 additions and 3 deletions

View File

@ -10,6 +10,7 @@ import android.support.media.ExifInterface;
import android.view.ViewGroup;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.uimanager.UIManagerModule;
@ -308,6 +309,27 @@ public class RNCameraViewHelper {
return exifMap;
}
public static void setExifData(ExifInterface exifInterface, WritableMap exifMap) {
ReadableMapKeySetIterator iterator = exifMap.keySetIterator();
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
switch (exifMap.getType(key)) {
case Null:
exifInterface.setAttribute(key, null);
break;
case Boolean:
exifInterface.setAttribute(key, Boolean.toString(exifMap.getBoolean(key)));
break;
case Number:
exifInterface.setAttribute(key, Double.toString(exifMap.getDouble(key)));
break;
case String:
exifInterface.setAttribute(key, exifMap.getString(key));
break;
}
}
}
public static Bitmap generateSimulatorPhoto(int width, int height) {
Bitmap fakePhoto = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(fakePhoto);

View File

@ -94,6 +94,8 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
}
try {
WritableMap fileExifData = null;
if (inputStream != null) {
ExifInterface exifInterface = new ExifInterface(inputStream);
// Get orientation of the image from mImageData via inputStream
@ -101,7 +103,10 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
ExifInterface.ORIENTATION_UNDEFINED);
// Rotate the bitmap to the proper orientation if needed
if (mOptions.hasKey("fixOrientation") && mOptions.getBoolean("fixOrientation") && orientation != ExifInterface.ORIENTATION_UNDEFINED) {
boolean fixOrientation = mOptions.hasKey("fixOrientation")
&& mOptions.getBoolean("fixOrientation")
&& orientation != ExifInterface.ORIENTATION_UNDEFINED;
if (fixOrientation) {
mBitmap = rotateBitmap(mBitmap, getImageRotation(orientation));
}
@ -113,9 +118,28 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
mBitmap = flipHorizontally(mBitmap);
}
WritableMap exifData = null;
boolean writeExifToResponse = mOptions.hasKey("exif") && mOptions.getBoolean("exif");
boolean writeExifToFile = mOptions.hasKey("writeExif") && mOptions.getBoolean("writeExif");
// Read Exif data if needed
if (writeExifToResponse || writeExifToFile) {
exifData = RNCameraViewHelper.getExifData(exifInterface);
}
// Write Exif data to output file if requested
if (writeExifToFile) {
fileExifData = Arguments.createMap();
fileExifData.merge(exifData);
fileExifData.putInt("width", mBitmap.getWidth());
fileExifData.putInt("height", mBitmap.getHeight());
if (fixOrientation) {
fileExifData.putInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}
}
// Write Exif data to the response if requested
if (mOptions.hasKey("exif") && mOptions.getBoolean("exif")) {
WritableMap exifData = RNCameraViewHelper.getExifData(exifInterface);
if (writeExifToResponse) {
response.putMap("exif", exifData);
}
}
@ -131,6 +155,11 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
// Write compressed image to file in cache directory unless otherwise specified
if (!mOptions.hasKey("doNotSave") || !mOptions.getBoolean("doNotSave")) {
String filePath = writeStreamToFile(imageStream);
if (fileExifData != null) {
ExifInterface fileExifInterface = new ExifInterface(filePath);
RNCameraViewHelper.setExifData(fileExifInterface, fileExifData);
fileExifInterface.saveAttributes();
}
File imageFile = new File(filePath);
String fileUri = Uri.fromFile(imageFile).toString();
response.putString("uri", fileUri);

View File

@ -99,6 +99,7 @@ type PictureOptions = {
base64?: boolean,
mirrorImage?: boolean,
exif?: boolean,
writeExif?: boolean,
width?: number,
fixOrientation?: boolean,
forceUpOrientation?: boolean,

1
types/index.d.ts vendored
View File

@ -353,6 +353,7 @@ interface TakePictureOptions {
/** Android only */
skipProcessing?: boolean;
fixOrientation?: boolean;
writeExif?: boolean;
/** iOS only */
forceUpOrientation?: boolean;