mirror of
https://github.com/status-im/react-native-camera.git
synced 2025-02-24 09:48:17 +00:00
parent
fd61e506e5
commit
06dc7ac5a7
@ -33,4 +33,5 @@ repositories {
|
||||
dependencies {
|
||||
compile "com.facebook.react:react-native:0.19.+"
|
||||
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.Matrix;
|
||||
import android.hardware.Camera;
|
||||
import android.media.CamcorderProfile;
|
||||
import android.media.MediaActionSound;
|
||||
import android.media.MediaRecorder;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.media.*;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
@ -21,6 +18,11 @@ import android.util.Base64;
|
||||
import android.util.Log;
|
||||
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.Promise;
|
||||
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.WritableNativeMap;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
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.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@ -493,6 +488,28 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
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) {
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
||||
Bitmap photo = BitmapFactory.decodeStream(inputStream);
|
||||
@ -501,25 +518,80 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
m.preScale(-1, 1);
|
||||
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 {
|
||||
result = compress(mirroredImage, 85);
|
||||
} catch (OutOfMemoryError e) {
|
||||
try {
|
||||
result = compress(mirroredImage, 70);
|
||||
} catch (OutOfMemoryError e2) {
|
||||
e.printStackTrace();
|
||||
metadata = ImageMetadataReader.readMetadata(
|
||||
new BufferedInputStream(new ByteArrayInputStream(data)), data.length
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
return data;
|
||||
} catch (IOException | ImageProcessingException | MetadataException e) {
|
||||
e.printStackTrace();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
private void rewriteOrientation(String path) {
|
||||
try {
|
||||
ExifInterface exif = new ExifInterface(path);
|
||||
exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_NORMAL));
|
||||
exif.saveAttributes();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] compress(Bitmap bitmap, int quality) throws OutOfMemoryError {
|
||||
@ -593,6 +665,8 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
}
|
||||
|
||||
data = fixOrientation(data);
|
||||
|
||||
camera.stopPreview();
|
||||
camera.startPreview();
|
||||
WritableMap response = new WritableNativeMap();
|
||||
@ -615,6 +689,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
return;
|
||||
}
|
||||
|
||||
rewriteOrientation(cameraRollFile.getAbsolutePath());
|
||||
addToMediaStore(cameraRollFile.getAbsolutePath());
|
||||
response.putString("path", Uri.fromFile(cameraRollFile).toString());
|
||||
promise.resolve(response);
|
||||
@ -633,6 +708,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
return;
|
||||
}
|
||||
|
||||
rewriteOrientation(pictureFile.getAbsolutePath());
|
||||
response.putString("path", Uri.fromFile(pictureFile).toString());
|
||||
promise.resolve(response);
|
||||
break;
|
||||
@ -649,6 +725,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
promise.reject(error);
|
||||
}
|
||||
|
||||
rewriteOrientation(tempFile.getAbsolutePath());
|
||||
response.putString("path", Uri.fromFile(tempFile).toString());
|
||||
promise.resolve(response);
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user