mirror of
https://github.com/status-im/react-native-camera.git
synced 2025-02-24 17:58:20 +00:00
parent
fd61e506e5
commit
06dc7ac5a7
@ -33,4 +33,5 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compile "com.facebook.react:react-native:0.19.+"
|
compile "com.facebook.react:react-native:0.19.+"
|
||||||
compile "com.google.zxing:core:3.2.1"
|
compile "com.google.zxing:core:3.2.1"
|
||||||
|
compile "com.drewnoakes:metadata-extractor:2.9.1"
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,7 @@ import android.graphics.Bitmap;
|
|||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
import android.media.CamcorderProfile;
|
import android.media.*;
|
||||||
import android.media.MediaActionSound;
|
|
||||||
import android.media.MediaRecorder;
|
|
||||||
import android.media.MediaScannerConnection;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
@ -21,6 +18,11 @@ import android.util.Base64;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
|
||||||
|
import com.drew.imaging.ImageMetadataReader;
|
||||||
|
import com.drew.imaging.ImageProcessingException;
|
||||||
|
import com.drew.metadata.Metadata;
|
||||||
|
import com.drew.metadata.MetadataException;
|
||||||
|
import com.drew.metadata.exif.ExifIFD0Directory;
|
||||||
import com.facebook.react.bridge.LifecycleEventListener;
|
import com.facebook.react.bridge.LifecycleEventListener;
|
||||||
import com.facebook.react.bridge.Promise;
|
import com.facebook.react.bridge.Promise;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
@ -30,14 +32,7 @@ import com.facebook.react.bridge.ReadableMap;
|
|||||||
import com.facebook.react.bridge.WritableMap;
|
import com.facebook.react.bridge.WritableMap;
|
||||||
import com.facebook.react.bridge.WritableNativeMap;
|
import com.facebook.react.bridge.WritableNativeMap;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -493,6 +488,28 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
|||||||
return byteArray;
|
return byteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] saveImage(InputStream is, Bitmap image) {
|
||||||
|
byte[] result = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = compress(image, 85);
|
||||||
|
} catch (OutOfMemoryError e) {
|
||||||
|
try {
|
||||||
|
result = compress(image, 70);
|
||||||
|
} catch (OutOfMemoryError e2) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] mirrorImage(byte[] data) {
|
private byte[] mirrorImage(byte[] data) {
|
||||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
||||||
Bitmap photo = BitmapFactory.decodeStream(inputStream);
|
Bitmap photo = BitmapFactory.decodeStream(inputStream);
|
||||||
@ -501,25 +518,80 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
|||||||
m.preScale(-1, 1);
|
m.preScale(-1, 1);
|
||||||
Bitmap mirroredImage = Bitmap.createBitmap(photo, 0, 0, photo.getWidth(), photo.getHeight(), m, false);
|
Bitmap mirroredImage = Bitmap.createBitmap(photo, 0, 0, photo.getWidth(), photo.getHeight(), m, false);
|
||||||
|
|
||||||
byte[] result = null;
|
return saveImage(inputStream, mirroredImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private byte[] rotate(byte[] data, int exifOrientation) {
|
||||||
|
final Matrix bitmapMatrix = new Matrix();
|
||||||
|
switch(exifOrientation)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bitmapMatrix.postScale(-1, 1);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
bitmapMatrix.postRotate(180);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
bitmapMatrix.postRotate(180);
|
||||||
|
bitmapMatrix.postScale(-1, 1);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
bitmapMatrix.postRotate(90);
|
||||||
|
bitmapMatrix.postScale(-1, 1);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
bitmapMatrix.postRotate(90);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
bitmapMatrix.postRotate(270);
|
||||||
|
bitmapMatrix.postScale(-1, 1);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
bitmapMatrix.postRotate(270);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
||||||
|
Bitmap decodedBitmap = BitmapFactory.decodeStream(inputStream);
|
||||||
|
final Bitmap transformedBitmap = Bitmap.createBitmap(
|
||||||
|
decodedBitmap, 0, 0, decodedBitmap.getWidth(), decodedBitmap.getHeight(), bitmapMatrix, false
|
||||||
|
);
|
||||||
|
|
||||||
|
return saveImage(inputStream, transformedBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] fixOrientation(byte[] data) {
|
||||||
|
final Metadata metadata;
|
||||||
try {
|
try {
|
||||||
result = compress(mirroredImage, 85);
|
metadata = ImageMetadataReader.readMetadata(
|
||||||
} catch (OutOfMemoryError e) {
|
new BufferedInputStream(new ByteArrayInputStream(data)), data.length
|
||||||
try {
|
);
|
||||||
result = compress(mirroredImage, 70);
|
|
||||||
} catch (OutOfMemoryError e2) {
|
final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
|
||||||
|
if (exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
|
||||||
|
final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
|
||||||
|
return rotate(data, exifOrientation);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
} catch (IOException | ImageProcessingException | MetadataException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void rewriteOrientation(String path) {
|
||||||
try {
|
try {
|
||||||
inputStream.close();
|
ExifInterface exif = new ExifInterface(path);
|
||||||
|
exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_NORMAL));
|
||||||
|
exif.saveAttributes();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
Log.e(TAG, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] compress(Bitmap bitmap, int quality) throws OutOfMemoryError {
|
private byte[] compress(Bitmap bitmap, int quality) throws OutOfMemoryError {
|
||||||
@ -593,6 +665,8 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = fixOrientation(data);
|
||||||
|
|
||||||
camera.stopPreview();
|
camera.stopPreview();
|
||||||
camera.startPreview();
|
camera.startPreview();
|
||||||
WritableMap response = new WritableNativeMap();
|
WritableMap response = new WritableNativeMap();
|
||||||
@ -615,6 +689,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rewriteOrientation(cameraRollFile.getAbsolutePath());
|
||||||
addToMediaStore(cameraRollFile.getAbsolutePath());
|
addToMediaStore(cameraRollFile.getAbsolutePath());
|
||||||
response.putString("path", Uri.fromFile(cameraRollFile).toString());
|
response.putString("path", Uri.fromFile(cameraRollFile).toString());
|
||||||
promise.resolve(response);
|
promise.resolve(response);
|
||||||
@ -633,6 +708,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rewriteOrientation(pictureFile.getAbsolutePath());
|
||||||
response.putString("path", Uri.fromFile(pictureFile).toString());
|
response.putString("path", Uri.fromFile(pictureFile).toString());
|
||||||
promise.resolve(response);
|
promise.resolve(response);
|
||||||
break;
|
break;
|
||||||
@ -649,6 +725,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
|||||||
promise.reject(error);
|
promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rewriteOrientation(tempFile.getAbsolutePath());
|
||||||
response.putString("path", Uri.fromFile(tempFile).toString());
|
response.putString("path", Uri.fromFile(tempFile).toString());
|
||||||
promise.resolve(response);
|
promise.resolve(response);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user