mirror of
https://github.com/status-im/react-native-camera.git
synced 2025-02-24 09:48:17 +00:00
Mirror image for Android (#399)
* Add mirrorImage support for Android * Release resources after mirroring * Mirror image only for TYPE_FRONT * Remove unnecessary annotation * Document mirrorImage for Android * Improved compression and error handling * Add support for mirroring on Android back camera too
This commit is contained in:
parent
2bbdf8ce91
commit
b01c64e773
@ -189,6 +189,7 @@ export default class Example extends React.Component {
|
||||
type={this.state.camera.type}
|
||||
flashMode={this.state.camera.flashMode}
|
||||
defaultTouchToFocus
|
||||
mirrorImage={false}
|
||||
/>
|
||||
<View style={[styles.overlay, styles.topOverlay]}>
|
||||
<TouchableOpacity
|
||||
|
@ -2,4 +2,4 @@ rootProject.name = 'Example'
|
||||
|
||||
include ':app'
|
||||
include ':react-native-camera'
|
||||
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
|
||||
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../../android')
|
||||
|
@ -243,9 +243,9 @@ By default, `onZoomChanged` is not defined and pinch-to-zoom is disabled.
|
||||
|
||||
If set to `true`, the device will not sleep while the camera preview is visible. This mimics the behavior of the default camera app, which keeps the device awake while open.
|
||||
|
||||
#### `iOS` `mirrorImage`
|
||||
#### `mirrorImage`
|
||||
|
||||
If set to `true`, the image returned will be mirrored..
|
||||
If set to `true`, the image returned will be mirrored.
|
||||
|
||||
## Component instance methods
|
||||
|
||||
|
@ -5,28 +5,48 @@
|
||||
|
||||
package com.lwansbrough.RCTCamera;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ContentValues;
|
||||
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.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import com.facebook.react.bridge.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.*;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
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.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
implements MediaRecorder.OnInfoListener, LifecycleEventListener {
|
||||
@ -393,6 +413,50 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
private byte[] mirrorImage(byte[] data) {
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
||||
Bitmap photo = BitmapFactory.decodeStream(inputStream);
|
||||
|
||||
Matrix m = new Matrix();
|
||||
m.preScale(-1, 1);
|
||||
Bitmap mirroredImage = Bitmap.createBitmap(photo, 0, 0, photo.getWidth(), photo.getHeight(), m, false);
|
||||
|
||||
byte[] result = null;
|
||||
|
||||
try {
|
||||
result = compress(mirroredImage, 85);
|
||||
} catch (OutOfMemoryError e) {
|
||||
try {
|
||||
result = compress(mirroredImage, 70);
|
||||
} catch (OutOfMemoryError e2) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private byte[] compress(Bitmap bitmap, int quality) throws OutOfMemoryError {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
|
||||
|
||||
try {
|
||||
return outputStream.toByteArray();
|
||||
} finally {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void capture(final ReadableMap options, final Promise promise) {
|
||||
int orientation = options.hasKey("orientation") ? options.getInt("orientation") : RCTCamera.getInstance().getOrientation();
|
||||
@ -435,10 +499,20 @@ public class RCTCameraModule extends ReactContextBaseJavaModule
|
||||
RCTCamera.getInstance().setCaptureQuality(options.getInt("type"), options.getString("quality"));
|
||||
}
|
||||
|
||||
final Boolean shouldMirror = options.hasKey("mirrorImage") && options.getBoolean("mirrorImage");
|
||||
|
||||
RCTCamera.getInstance().adjustCameraRotationToDeviceOrientation(options.getInt("type"), deviceOrientation);
|
||||
camera.takePicture(null, null, new Camera.PictureCallback() {
|
||||
@Override
|
||||
public void onPictureTaken(byte[] data, Camera camera) {
|
||||
|
||||
if (shouldMirror) {
|
||||
data = mirrorImage(data);
|
||||
if (data == null) {
|
||||
promise.reject("Error mirroring image");
|
||||
}
|
||||
}
|
||||
|
||||
camera.stopPreview();
|
||||
camera.startPreview();
|
||||
WritableMap response = new WritableNativeMap();
|
||||
|
Loading…
x
Reference in New Issue
Block a user