mirror of
https://github.com/status-im/react-native-camera.git
synced 2026-08-31 13:41:08 +00:00
Add GoogleVision barcode scanner.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package org.reactnative.barcodedetector;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BarcodeFormatUtils {
|
||||
|
||||
public static final SparseArray<String> FORMATS;
|
||||
public static final Map<String, Integer> REVERSE_FORMATS;
|
||||
|
||||
private static final String UNKNOWN_FORMAT_STRING = "UNKNOWN_FORMAT";
|
||||
private static final int UNKNOWN_FORMAT_INT = -1;
|
||||
|
||||
static {
|
||||
// Initialize integer to string map
|
||||
SparseArray<String> map = new SparseArray<>();
|
||||
map.put(Barcode.CODE_128, "CODE_128");
|
||||
map.put(Barcode.CODE_39, "CODE_39");
|
||||
map.put(Barcode.CODE_93, "CODE_93");
|
||||
map.put(Barcode.CODABAR, "CODABAR");
|
||||
map.put(Barcode.DATA_MATRIX, "DATA_MATRIX");
|
||||
map.put(Barcode.EAN_13, "EAN_13");
|
||||
map.put(Barcode.EAN_8, "EAN_8");
|
||||
map.put(Barcode.ITF, "ITF");
|
||||
map.put(Barcode.QR_CODE, "QR_CODE");
|
||||
map.put(Barcode.UPC_A, "UPC_A");
|
||||
map.put(Barcode.UPC_E, "UPC_E");
|
||||
map.put(Barcode.PDF417, "PDF417");
|
||||
map.put(Barcode.AZTEC, "AZTEC");
|
||||
FORMATS = map;
|
||||
|
||||
|
||||
// Initialize string to integer map
|
||||
Map<String, Integer> rmap = new HashMap<>();
|
||||
for (int i = 0; i < map.size(); i++) {
|
||||
rmap.put(map.valueAt(i), map.keyAt(i));
|
||||
}
|
||||
|
||||
rmap.put("ALL", 0);
|
||||
REVERSE_FORMATS = Collections.unmodifiableMap(rmap);
|
||||
}
|
||||
|
||||
public static String get(int format) {
|
||||
return FORMATS.get(format, UNKNOWN_FORMAT_STRING);
|
||||
}
|
||||
|
||||
public static int get(String format) {
|
||||
if (REVERSE_FORMATS.containsKey(format)) {
|
||||
return REVERSE_FORMATS.get(format);
|
||||
}
|
||||
|
||||
return UNKNOWN_FORMAT_INT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.reactnative.barcodedetector;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.SparseArray;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import com.google.android.gms.vision.barcode.BarcodeDetector;
|
||||
import org.reactnative.camera.utils.ImageDimensions;
|
||||
import org.reactnative.frame.RNFrame;
|
||||
|
||||
public class RNBarcodeDetector {
|
||||
|
||||
private BarcodeDetector mBarcodeDetector = null;
|
||||
private ImageDimensions mPreviousDimensions;
|
||||
private BarcodeDetector.Builder mBuilder;
|
||||
|
||||
private int mBarcodeType = Barcode.ALL_FORMATS;
|
||||
|
||||
public RNBarcodeDetector(Context context) {
|
||||
mBuilder = new BarcodeDetector.Builder(context)
|
||||
.setBarcodeFormats(mBarcodeType);
|
||||
}
|
||||
|
||||
// Public API
|
||||
|
||||
public boolean isOperational() {
|
||||
if (mBarcodeDetector == null) {
|
||||
createBarcodeDetector();
|
||||
}
|
||||
|
||||
return mBarcodeDetector.isOperational();
|
||||
}
|
||||
|
||||
public SparseArray<Barcode> detect(RNFrame frame) {
|
||||
// If the frame has different dimensions, create another barcode detector.
|
||||
// Otherwise we will most likely get nasty "inconsistent image dimensions" error from detector
|
||||
// and no barcode will be detected.
|
||||
if (!frame.getDimensions().equals(mPreviousDimensions)) {
|
||||
releaseBarcodeDetector();
|
||||
}
|
||||
|
||||
if (mBarcodeDetector == null) {
|
||||
createBarcodeDetector();
|
||||
mPreviousDimensions = frame.getDimensions();
|
||||
}
|
||||
|
||||
return mBarcodeDetector.detect(frame.getFrame());
|
||||
}
|
||||
|
||||
public void setBarcodeType(int barcodeType) {
|
||||
if (barcodeType != mBarcodeType) {
|
||||
release();
|
||||
mBuilder.setBarcodeFormats(barcodeType);
|
||||
mBarcodeType = barcodeType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void release() {
|
||||
releaseBarcodeDetector();
|
||||
mPreviousDimensions = null;
|
||||
}
|
||||
|
||||
// Lifecycle methods
|
||||
|
||||
private void releaseBarcodeDetector() {
|
||||
if (mBarcodeDetector != null) {
|
||||
mBarcodeDetector.release();
|
||||
mBarcodeDetector = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void createBarcodeDetector() {
|
||||
mBarcodeDetector = mBuilder.build();
|
||||
}
|
||||
}
|
||||
@@ -2,35 +2,25 @@ package org.reactnative.camera;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
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.WritableArray;
|
||||
import com.facebook.react.bridge.*;
|
||||
import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
||||
import com.facebook.react.uimanager.UIBlock;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.google.android.cameraview.AspectRatio;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import org.reactnative.barcodedetector.BarcodeFormatUtils;
|
||||
import org.reactnative.camera.tasks.ResolveTakenPictureAsyncTask;
|
||||
import org.reactnative.camera.utils.ScopedContext;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class CameraModule extends ReactContextBaseJavaModule {
|
||||
private static final String TAG = "CameraModule";
|
||||
|
||||
@@ -123,6 +113,11 @@ public class CameraModule extends ReactContextBaseJavaModule {
|
||||
});
|
||||
}
|
||||
}));
|
||||
put("GoogleVisionBarcodeDetection", Collections.unmodifiableMap(new HashMap<String, Object>() {
|
||||
{
|
||||
put("BarcodeType", BarcodeFormatUtils.REVERSE_FORMATS);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private Map<String, Object> getTypeConstants() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.reactnative.camera;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
@@ -19,6 +18,7 @@ public class CameraViewManager extends ViewGroupManager<RNCameraView> {
|
||||
EVENT_ON_MOUNT_ERROR("onMountError"),
|
||||
EVENT_ON_BAR_CODE_READ("onBarCodeRead"),
|
||||
EVENT_ON_FACES_DETECTED("onFacesDetected"),
|
||||
EVENT_ON_BARCODES_DETECTED("onGoogleVisionBarcodesDetected"),
|
||||
EVENT_ON_FACE_DETECTION_ERROR("onFaceDetectionError"),
|
||||
EVENT_ON_TEXT_RECOGNIZED("onTextRecognized");
|
||||
|
||||
@@ -145,6 +145,16 @@ public class CameraViewManager extends ViewGroupManager<RNCameraView> {
|
||||
view.setFaceDetectionClassifications(classifications);
|
||||
}
|
||||
|
||||
@ReactProp(name = "googleVisionBarcodeDetectorEnabled")
|
||||
public void setGoogleVisionBarcodeDetecting(RNCameraView view, boolean barcodeDetectorEnabled) {
|
||||
view.setShouldDetectBarcodes(barcodeDetectorEnabled);
|
||||
}
|
||||
|
||||
@ReactProp(name = "googleVisionBarcodeType")
|
||||
public void setGoogleVisionBarcodeType(RNCameraView view, int barcodeType) {
|
||||
view.setGoogleVisionBarcodeType(barcodeType);
|
||||
}
|
||||
|
||||
@ReactProp(name = "textRecognizerEnabled")
|
||||
public void setTextRecognizing(RNCameraView view, boolean textRecognizerEnabled) {
|
||||
view.setShouldRecognizeText(textRecognizerEnabled);
|
||||
|
||||
@@ -8,8 +8,6 @@ import com.facebook.react.uimanager.ViewManager;
|
||||
import com.lwansbrough.RCTCamera.RCTCameraModule;
|
||||
import com.lwansbrough.RCTCamera.RCTCameraViewManager;
|
||||
|
||||
import org.reactnative.camera.CameraModule;
|
||||
import org.reactnative.camera.CameraViewManager;
|
||||
import org.reactnative.facedetector.FaceDetectorModule;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -9,46 +9,31 @@ import android.os.Build;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.*;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.google.android.cameraview.CameraView;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import com.google.android.gms.vision.face.Face;
|
||||
import com.google.android.gms.vision.text.Text;
|
||||
import com.google.android.gms.vision.text.TextBlock;
|
||||
import com.google.android.gms.vision.text.TextRecognizer;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.MultiFormatReader;
|
||||
import com.google.zxing.Result;
|
||||
|
||||
import org.reactnative.camera.tasks.BarCodeScannerAsyncTask;
|
||||
import org.reactnative.camera.tasks.BarCodeScannerAsyncTaskDelegate;
|
||||
import org.reactnative.camera.tasks.FaceDetectorAsyncTask;
|
||||
import org.reactnative.camera.tasks.FaceDetectorAsyncTaskDelegate;
|
||||
import org.reactnative.camera.tasks.ResolveTakenPictureAsyncTask;
|
||||
import org.reactnative.camera.tasks.TextRecognizerAsyncTask;
|
||||
import org.reactnative.camera.tasks.TextRecognizerAsyncTaskDelegate;
|
||||
import org.reactnative.camera.tasks.*;
|
||||
import org.reactnative.camera.utils.ImageDimensions;
|
||||
import org.reactnative.camera.utils.RNFileUtils;
|
||||
import org.reactnative.barcodedetector.RNBarcodeDetector;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class RNCameraView extends CameraView implements LifecycleEventListener, BarCodeScannerAsyncTaskDelegate, FaceDetectorAsyncTaskDelegate,
|
||||
TextRecognizerAsyncTaskDelegate {
|
||||
BarcodeDetectorAsyncTaskDelegate, TextRecognizerAsyncTaskDelegate {
|
||||
private ThemedReactContext mThemedReactContext;
|
||||
private Queue<Promise> mPictureTakenPromises = new ConcurrentLinkedQueue<>();
|
||||
private Map<Promise, ReadableMap> mPictureTakenOptions = new ConcurrentHashMap<>();
|
||||
@@ -63,18 +48,22 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
// Concurrency lock for scanners to avoid flooding the runtime
|
||||
public volatile boolean barCodeScannerTaskLock = false;
|
||||
public volatile boolean faceDetectorTaskLock = false;
|
||||
public volatile boolean barcodeDetectorTaskLock = false;
|
||||
public volatile boolean textRecognizerTaskLock = false;
|
||||
|
||||
// Scanning-related properties
|
||||
private final MultiFormatReader mMultiFormatReader = new MultiFormatReader();
|
||||
private final RNFaceDetector mFaceDetector;
|
||||
private final RNBarcodeDetector mBarcodeDetector;
|
||||
private final TextRecognizer mTextRecognizer;
|
||||
private boolean mShouldDetectFaces = false;
|
||||
private boolean mShouldDetectBarcodes = false;
|
||||
private boolean mShouldScanBarCodes = false;
|
||||
private boolean mShouldRecognizeText = false;
|
||||
private int mFaceDetectorMode = RNFaceDetector.FAST_MODE;
|
||||
private int mFaceDetectionLandmarks = RNFaceDetector.NO_LANDMARKS;
|
||||
private int mFaceDetectionClassifications = RNFaceDetector.NO_CLASSIFICATIONS;
|
||||
private int mGoogleVisionBarCodeType = Barcode.ALL_FORMATS;
|
||||
|
||||
public RNCameraView(ThemedReactContext themedReactContext) {
|
||||
super(themedReactContext, true);
|
||||
@@ -82,6 +71,8 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
mThemedReactContext = themedReactContext;
|
||||
mFaceDetector = new RNFaceDetector(themedReactContext);
|
||||
setupFaceDetector();
|
||||
mBarcodeDetector = new RNBarcodeDetector(themedReactContext);
|
||||
setupBarcodeDetector();
|
||||
mTextRecognizer = new TextRecognizer.Builder(themedReactContext).build();
|
||||
themedReactContext.addLifecycleEventListener(this);
|
||||
|
||||
@@ -118,7 +109,7 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] rotateImage(byte[]imageData,int height,int width){
|
||||
private byte[] rotateImage(byte[] imageData, int height, int width) {
|
||||
byte[] rotated = new byte[imageData.length];
|
||||
for (int y = 0; y < width; y++) {
|
||||
for (int x = 0; x < height; x++) {
|
||||
@@ -131,13 +122,13 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
@Override
|
||||
public void onFramePreview(CameraView cameraView, byte[] data, int width, int height, int rotation) {
|
||||
int correctRotation = RNCameraViewHelper.getCorrectCameraRotation(rotation, getFacing());
|
||||
int correctWidth=width;
|
||||
int correctHeight=height;
|
||||
byte[] correctData=data;
|
||||
if(correctRotation==90){
|
||||
correctWidth=height;
|
||||
correctHeight=width;
|
||||
correctData=rotateImage(data,correctHeight,correctWidth);
|
||||
int correctWidth = width;
|
||||
int correctHeight = height;
|
||||
byte[] correctData = data;
|
||||
if (correctRotation == 90) {
|
||||
correctWidth = height;
|
||||
correctHeight = width;
|
||||
correctData = rotateImage(data, correctHeight, correctWidth);
|
||||
}
|
||||
if (mShouldScanBarCodes && !barCodeScannerTaskLock && cameraView instanceof BarCodeScannerAsyncTaskDelegate) {
|
||||
barCodeScannerTaskLock = true;
|
||||
@@ -151,6 +142,12 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
new FaceDetectorAsyncTask(delegate, mFaceDetector, correctData, correctWidth, correctHeight, correctRotation).execute();
|
||||
}
|
||||
|
||||
if (mShouldDetectBarcodes && !barcodeDetectorTaskLock && cameraView instanceof BarcodeDetectorAsyncTaskDelegate) {
|
||||
barcodeDetectorTaskLock = true;
|
||||
BarcodeDetectorAsyncTaskDelegate delegate = (BarcodeDetectorAsyncTaskDelegate) cameraView;
|
||||
new BarcodeDetectorAsyncTask(delegate, mBarcodeDetector, correctData, correctWidth, correctHeight, correctRotation).execute();
|
||||
}
|
||||
|
||||
if (mShouldRecognizeText && !textRecognizerTaskLock && cameraView instanceof TextRecognizerAsyncTaskDelegate) {
|
||||
textRecognizerTaskLock = true;
|
||||
TextRecognizerAsyncTaskDelegate delegate = (TextRecognizerAsyncTaskDelegate) cameraView;
|
||||
@@ -177,11 +174,11 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
correctWidth = (int) width;
|
||||
} else {
|
||||
correctHeight = (int) height;
|
||||
correctWidth = (int)(height*ratio);
|
||||
correctWidth = (int) (height * ratio);
|
||||
}
|
||||
int paddingX = (int) ((width - correctWidth) / 2);
|
||||
int paddingY = (int) ((height - correctHeight) / 2);
|
||||
preview.layout(paddingX, paddingY, correctWidth+paddingX, correctHeight+paddingY);
|
||||
preview.layout(paddingX, paddingY, correctWidth + paddingX, correctHeight + paddingY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -265,7 +262,7 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
|
||||
public void setShouldScanBarCodes(boolean shouldScanBarCodes) {
|
||||
this.mShouldScanBarCodes = shouldScanBarCodes;
|
||||
setScanning(mShouldDetectFaces || mShouldScanBarCodes || mShouldRecognizeText);
|
||||
setScanning(mShouldDetectFaces || mShouldDetectBarcodes || mShouldScanBarCodes || mShouldRecognizeText);
|
||||
}
|
||||
|
||||
public void onBarCodeRead(Result barCode) {
|
||||
@@ -315,7 +312,12 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
|
||||
public void setShouldDetectFaces(boolean shouldDetectFaces) {
|
||||
this.mShouldDetectFaces = shouldDetectFaces;
|
||||
setScanning(mShouldDetectFaces || mShouldScanBarCodes || mShouldRecognizeText);
|
||||
setScanning(mShouldDetectFaces || mShouldDetectBarcodes || mShouldScanBarCodes || mShouldRecognizeText);
|
||||
}
|
||||
|
||||
public void setShouldDetectBarcodes(boolean shouldDetectBarcodes) {
|
||||
this.mShouldDetectBarcodes = shouldDetectBarcodes;
|
||||
setScanning(mShouldDetectFaces || mShouldDetectBarcodes || mShouldScanBarCodes || mShouldRecognizeText);
|
||||
}
|
||||
|
||||
public void onFacesDetected(SparseArray<Face> facesReported, int sourceWidth, int sourceHeight, int sourceRotation) {
|
||||
@@ -342,9 +344,46 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
faceDetectorTaskLock = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial setup of the barcode detector
|
||||
*/
|
||||
private void setupBarcodeDetector() {
|
||||
mBarcodeDetector.setBarcodeType(mGoogleVisionBarCodeType);
|
||||
}
|
||||
|
||||
public void setGoogleVisionBarcodeType(int barcodeType) {
|
||||
mGoogleVisionBarCodeType = barcodeType;
|
||||
if (mBarcodeDetector != null) {
|
||||
mBarcodeDetector.setBarcodeType(barcodeType);
|
||||
}
|
||||
}
|
||||
|
||||
public void onBarcodesDetected(SparseArray<Barcode> barcodesReported, int sourceWidth, int sourceHeight, int sourceRotation) {
|
||||
if (!mShouldDetectBarcodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
SparseArray<Barcode> barcodesDetected = barcodesReported == null ? new SparseArray<Barcode>() : barcodesReported;
|
||||
|
||||
RNCameraViewHelper.emitBarcodesDetectedEvent(this, barcodesDetected);
|
||||
}
|
||||
|
||||
public void onBarcodeDetectionError(RNBarcodeDetector barcodeDetector) {
|
||||
if (!mShouldDetectBarcodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
RNCameraViewHelper.emitBarcodeDetectionErrorEvent(this, barcodeDetector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBarcodeDetectingTaskCompleted() {
|
||||
barcodeDetectorTaskLock = false;
|
||||
}
|
||||
|
||||
public void setShouldRecognizeText(boolean shouldRecognizeText) {
|
||||
this.mShouldRecognizeText = shouldRecognizeText;
|
||||
setScanning(mShouldDetectFaces || mShouldScanBarCodes || mShouldRecognizeText);
|
||||
setScanning(mShouldDetectFaces || mShouldDetectBarcodes || mShouldScanBarCodes || mShouldRecognizeText);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -392,6 +431,7 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
mFaceDetector.release();
|
||||
mBarcodeDetector.release();
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,161 +9,155 @@ import android.os.Build;
|
||||
import android.support.media.ExifInterface;
|
||||
import android.util.SparseArray;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.google.android.cameraview.CameraView;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import com.google.android.gms.vision.face.Face;
|
||||
import com.google.android.gms.vision.text.TextBlock;
|
||||
import com.google.zxing.Result;
|
||||
|
||||
import org.reactnative.camera.events.BarCodeReadEvent;
|
||||
import org.reactnative.camera.events.CameraMountErrorEvent;
|
||||
import org.reactnative.camera.events.CameraReadyEvent;
|
||||
import org.reactnative.camera.events.FaceDetectionErrorEvent;
|
||||
import org.reactnative.camera.events.FacesDetectedEvent;
|
||||
import org.reactnative.camera.events.TextRecognizedEvent;
|
||||
import org.reactnative.camera.events.*;
|
||||
import org.reactnative.camera.utils.ImageDimensions;
|
||||
import org.reactnative.barcodedetector.RNBarcodeDetector;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
public class RNCameraViewHelper {
|
||||
|
||||
public static final String[][] exifTags = new String[][]{
|
||||
{"string", ExifInterface.TAG_ARTIST},
|
||||
{"int", ExifInterface.TAG_BITS_PER_SAMPLE},
|
||||
{"int", ExifInterface.TAG_COMPRESSION},
|
||||
{"string", ExifInterface.TAG_COPYRIGHT},
|
||||
{"string", ExifInterface.TAG_DATETIME},
|
||||
{"string", ExifInterface.TAG_IMAGE_DESCRIPTION},
|
||||
{"int", ExifInterface.TAG_IMAGE_LENGTH},
|
||||
{"int", ExifInterface.TAG_IMAGE_WIDTH},
|
||||
{"int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT},
|
||||
{"int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH},
|
||||
{"string", ExifInterface.TAG_MAKE},
|
||||
{"string", ExifInterface.TAG_MODEL},
|
||||
{"int", ExifInterface.TAG_ORIENTATION},
|
||||
{"int", ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION},
|
||||
{"int", ExifInterface.TAG_PLANAR_CONFIGURATION},
|
||||
{"double", ExifInterface.TAG_PRIMARY_CHROMATICITIES},
|
||||
{"double", ExifInterface.TAG_REFERENCE_BLACK_WHITE},
|
||||
{"int", ExifInterface.TAG_RESOLUTION_UNIT},
|
||||
{"int", ExifInterface.TAG_ROWS_PER_STRIP},
|
||||
{"int", ExifInterface.TAG_SAMPLES_PER_PIXEL},
|
||||
{"string", ExifInterface.TAG_SOFTWARE},
|
||||
{"int", ExifInterface.TAG_STRIP_BYTE_COUNTS},
|
||||
{"int", ExifInterface.TAG_STRIP_OFFSETS},
|
||||
{"int", ExifInterface.TAG_TRANSFER_FUNCTION},
|
||||
{"double", ExifInterface.TAG_WHITE_POINT},
|
||||
{"double", ExifInterface.TAG_X_RESOLUTION},
|
||||
{"double", ExifInterface.TAG_Y_CB_CR_COEFFICIENTS},
|
||||
{"int", ExifInterface.TAG_Y_CB_CR_POSITIONING},
|
||||
{"int", ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING},
|
||||
{"double", ExifInterface.TAG_Y_RESOLUTION},
|
||||
{"double", ExifInterface.TAG_APERTURE_VALUE},
|
||||
{"double", ExifInterface.TAG_BRIGHTNESS_VALUE},
|
||||
{"string", ExifInterface.TAG_CFA_PATTERN},
|
||||
{"int", ExifInterface.TAG_COLOR_SPACE},
|
||||
{"string", ExifInterface.TAG_COMPONENTS_CONFIGURATION},
|
||||
{"double", ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL},
|
||||
{"int", ExifInterface.TAG_CONTRAST},
|
||||
{"int", ExifInterface.TAG_CUSTOM_RENDERED},
|
||||
{"string", ExifInterface.TAG_DATETIME_DIGITIZED},
|
||||
{"string", ExifInterface.TAG_DATETIME_ORIGINAL},
|
||||
{"string", ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION},
|
||||
{"double", ExifInterface.TAG_DIGITAL_ZOOM_RATIO},
|
||||
{"string", ExifInterface.TAG_EXIF_VERSION},
|
||||
{"double", ExifInterface.TAG_EXPOSURE_BIAS_VALUE},
|
||||
{"double", ExifInterface.TAG_EXPOSURE_INDEX},
|
||||
{"int", ExifInterface.TAG_EXPOSURE_MODE},
|
||||
{"int", ExifInterface.TAG_EXPOSURE_PROGRAM},
|
||||
{"double", ExifInterface.TAG_EXPOSURE_TIME},
|
||||
{"double", ExifInterface.TAG_F_NUMBER},
|
||||
{"string", ExifInterface.TAG_FILE_SOURCE},
|
||||
{"int", ExifInterface.TAG_FLASH},
|
||||
{"double", ExifInterface.TAG_FLASH_ENERGY},
|
||||
{"string", ExifInterface.TAG_FLASHPIX_VERSION},
|
||||
{"double", ExifInterface.TAG_FOCAL_LENGTH},
|
||||
{"int", ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM},
|
||||
{"int", ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT},
|
||||
{"double", ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION},
|
||||
{"double", ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION},
|
||||
{"int", ExifInterface.TAG_GAIN_CONTROL},
|
||||
{"int", ExifInterface.TAG_ISO_SPEED_RATINGS},
|
||||
{"string", ExifInterface.TAG_IMAGE_UNIQUE_ID},
|
||||
{"int", ExifInterface.TAG_LIGHT_SOURCE},
|
||||
{"string", ExifInterface.TAG_MAKER_NOTE},
|
||||
{"double", ExifInterface.TAG_MAX_APERTURE_VALUE},
|
||||
{"int", ExifInterface.TAG_METERING_MODE},
|
||||
{"int", ExifInterface.TAG_NEW_SUBFILE_TYPE},
|
||||
{"string", ExifInterface.TAG_OECF},
|
||||
{"int", ExifInterface.TAG_PIXEL_X_DIMENSION},
|
||||
{"int", ExifInterface.TAG_PIXEL_Y_DIMENSION},
|
||||
{"string", ExifInterface.TAG_RELATED_SOUND_FILE},
|
||||
{"int", ExifInterface.TAG_SATURATION},
|
||||
{"int", ExifInterface.TAG_SCENE_CAPTURE_TYPE},
|
||||
{"string", ExifInterface.TAG_SCENE_TYPE},
|
||||
{"int", ExifInterface.TAG_SENSING_METHOD},
|
||||
{"int", ExifInterface.TAG_SHARPNESS},
|
||||
{"double", ExifInterface.TAG_SHUTTER_SPEED_VALUE},
|
||||
{"string", ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE},
|
||||
{"string", ExifInterface.TAG_SPECTRAL_SENSITIVITY},
|
||||
{"int", ExifInterface.TAG_SUBFILE_TYPE},
|
||||
{"string", ExifInterface.TAG_SUBSEC_TIME},
|
||||
{"string", ExifInterface.TAG_SUBSEC_TIME_DIGITIZED},
|
||||
{"string", ExifInterface.TAG_SUBSEC_TIME_ORIGINAL},
|
||||
{"int", ExifInterface.TAG_SUBJECT_AREA},
|
||||
{"double", ExifInterface.TAG_SUBJECT_DISTANCE},
|
||||
{"int", ExifInterface.TAG_SUBJECT_DISTANCE_RANGE},
|
||||
{"int", ExifInterface.TAG_SUBJECT_LOCATION},
|
||||
{"string", ExifInterface.TAG_USER_COMMENT},
|
||||
{"int", ExifInterface.TAG_WHITE_BALANCE},
|
||||
{"int", ExifInterface.TAG_GPS_ALTITUDE_REF},
|
||||
{"string", ExifInterface.TAG_GPS_AREA_INFORMATION},
|
||||
{"double", ExifInterface.TAG_GPS_DOP},
|
||||
{"string", ExifInterface.TAG_GPS_DATESTAMP},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_BEARING},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_BEARING_REF},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_DISTANCE},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_DISTANCE_REF},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_LATITUDE},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_LATITUDE_REF},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_LONGITUDE},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_LONGITUDE_REF},
|
||||
{"int", ExifInterface.TAG_GPS_DIFFERENTIAL},
|
||||
{"double", ExifInterface.TAG_GPS_IMG_DIRECTION},
|
||||
{"string", ExifInterface.TAG_GPS_IMG_DIRECTION_REF},
|
||||
{"string", ExifInterface.TAG_GPS_LATITUDE_REF},
|
||||
{"string", ExifInterface.TAG_GPS_LONGITUDE_REF},
|
||||
{"string", ExifInterface.TAG_GPS_MAP_DATUM},
|
||||
{"string", ExifInterface.TAG_GPS_MEASURE_MODE},
|
||||
{"string", ExifInterface.TAG_GPS_PROCESSING_METHOD},
|
||||
{"string", ExifInterface.TAG_GPS_SATELLITES},
|
||||
{"double", ExifInterface.TAG_GPS_SPEED},
|
||||
{"string", ExifInterface.TAG_GPS_SPEED_REF},
|
||||
{"string", ExifInterface.TAG_GPS_STATUS},
|
||||
{"string", ExifInterface.TAG_GPS_TIMESTAMP},
|
||||
{"double", ExifInterface.TAG_GPS_TRACK},
|
||||
{"string", ExifInterface.TAG_GPS_TRACK_REF},
|
||||
{"string", ExifInterface.TAG_GPS_VERSION_ID},
|
||||
{"string", ExifInterface.TAG_INTEROPERABILITY_INDEX},
|
||||
{"int", ExifInterface.TAG_THUMBNAIL_IMAGE_LENGTH},
|
||||
{"int", ExifInterface.TAG_THUMBNAIL_IMAGE_WIDTH},
|
||||
{"int", ExifInterface.TAG_DNG_VERSION},
|
||||
{"int", ExifInterface.TAG_DEFAULT_CROP_SIZE},
|
||||
{"int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_START},
|
||||
{"int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_LENGTH},
|
||||
{"int", ExifInterface.TAG_ORF_ASPECT_FRAME},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_BOTTOM_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_LEFT_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_RIGHT_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_TOP_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_ISO},
|
||||
{"string", ExifInterface.TAG_ARTIST},
|
||||
{"int", ExifInterface.TAG_BITS_PER_SAMPLE},
|
||||
{"int", ExifInterface.TAG_COMPRESSION},
|
||||
{"string", ExifInterface.TAG_COPYRIGHT},
|
||||
{"string", ExifInterface.TAG_DATETIME},
|
||||
{"string", ExifInterface.TAG_IMAGE_DESCRIPTION},
|
||||
{"int", ExifInterface.TAG_IMAGE_LENGTH},
|
||||
{"int", ExifInterface.TAG_IMAGE_WIDTH},
|
||||
{"int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT},
|
||||
{"int", ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH},
|
||||
{"string", ExifInterface.TAG_MAKE},
|
||||
{"string", ExifInterface.TAG_MODEL},
|
||||
{"int", ExifInterface.TAG_ORIENTATION},
|
||||
{"int", ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION},
|
||||
{"int", ExifInterface.TAG_PLANAR_CONFIGURATION},
|
||||
{"double", ExifInterface.TAG_PRIMARY_CHROMATICITIES},
|
||||
{"double", ExifInterface.TAG_REFERENCE_BLACK_WHITE},
|
||||
{"int", ExifInterface.TAG_RESOLUTION_UNIT},
|
||||
{"int", ExifInterface.TAG_ROWS_PER_STRIP},
|
||||
{"int", ExifInterface.TAG_SAMPLES_PER_PIXEL},
|
||||
{"string", ExifInterface.TAG_SOFTWARE},
|
||||
{"int", ExifInterface.TAG_STRIP_BYTE_COUNTS},
|
||||
{"int", ExifInterface.TAG_STRIP_OFFSETS},
|
||||
{"int", ExifInterface.TAG_TRANSFER_FUNCTION},
|
||||
{"double", ExifInterface.TAG_WHITE_POINT},
|
||||
{"double", ExifInterface.TAG_X_RESOLUTION},
|
||||
{"double", ExifInterface.TAG_Y_CB_CR_COEFFICIENTS},
|
||||
{"int", ExifInterface.TAG_Y_CB_CR_POSITIONING},
|
||||
{"int", ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING},
|
||||
{"double", ExifInterface.TAG_Y_RESOLUTION},
|
||||
{"double", ExifInterface.TAG_APERTURE_VALUE},
|
||||
{"double", ExifInterface.TAG_BRIGHTNESS_VALUE},
|
||||
{"string", ExifInterface.TAG_CFA_PATTERN},
|
||||
{"int", ExifInterface.TAG_COLOR_SPACE},
|
||||
{"string", ExifInterface.TAG_COMPONENTS_CONFIGURATION},
|
||||
{"double", ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL},
|
||||
{"int", ExifInterface.TAG_CONTRAST},
|
||||
{"int", ExifInterface.TAG_CUSTOM_RENDERED},
|
||||
{"string", ExifInterface.TAG_DATETIME_DIGITIZED},
|
||||
{"string", ExifInterface.TAG_DATETIME_ORIGINAL},
|
||||
{"string", ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION},
|
||||
{"double", ExifInterface.TAG_DIGITAL_ZOOM_RATIO},
|
||||
{"string", ExifInterface.TAG_EXIF_VERSION},
|
||||
{"double", ExifInterface.TAG_EXPOSURE_BIAS_VALUE},
|
||||
{"double", ExifInterface.TAG_EXPOSURE_INDEX},
|
||||
{"int", ExifInterface.TAG_EXPOSURE_MODE},
|
||||
{"int", ExifInterface.TAG_EXPOSURE_PROGRAM},
|
||||
{"double", ExifInterface.TAG_EXPOSURE_TIME},
|
||||
{"double", ExifInterface.TAG_F_NUMBER},
|
||||
{"string", ExifInterface.TAG_FILE_SOURCE},
|
||||
{"int", ExifInterface.TAG_FLASH},
|
||||
{"double", ExifInterface.TAG_FLASH_ENERGY},
|
||||
{"string", ExifInterface.TAG_FLASHPIX_VERSION},
|
||||
{"double", ExifInterface.TAG_FOCAL_LENGTH},
|
||||
{"int", ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM},
|
||||
{"int", ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT},
|
||||
{"double", ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION},
|
||||
{"double", ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION},
|
||||
{"int", ExifInterface.TAG_GAIN_CONTROL},
|
||||
{"int", ExifInterface.TAG_ISO_SPEED_RATINGS},
|
||||
{"string", ExifInterface.TAG_IMAGE_UNIQUE_ID},
|
||||
{"int", ExifInterface.TAG_LIGHT_SOURCE},
|
||||
{"string", ExifInterface.TAG_MAKER_NOTE},
|
||||
{"double", ExifInterface.TAG_MAX_APERTURE_VALUE},
|
||||
{"int", ExifInterface.TAG_METERING_MODE},
|
||||
{"int", ExifInterface.TAG_NEW_SUBFILE_TYPE},
|
||||
{"string", ExifInterface.TAG_OECF},
|
||||
{"int", ExifInterface.TAG_PIXEL_X_DIMENSION},
|
||||
{"int", ExifInterface.TAG_PIXEL_Y_DIMENSION},
|
||||
{"string", ExifInterface.TAG_RELATED_SOUND_FILE},
|
||||
{"int", ExifInterface.TAG_SATURATION},
|
||||
{"int", ExifInterface.TAG_SCENE_CAPTURE_TYPE},
|
||||
{"string", ExifInterface.TAG_SCENE_TYPE},
|
||||
{"int", ExifInterface.TAG_SENSING_METHOD},
|
||||
{"int", ExifInterface.TAG_SHARPNESS},
|
||||
{"double", ExifInterface.TAG_SHUTTER_SPEED_VALUE},
|
||||
{"string", ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE},
|
||||
{"string", ExifInterface.TAG_SPECTRAL_SENSITIVITY},
|
||||
{"int", ExifInterface.TAG_SUBFILE_TYPE},
|
||||
{"string", ExifInterface.TAG_SUBSEC_TIME},
|
||||
{"string", ExifInterface.TAG_SUBSEC_TIME_DIGITIZED},
|
||||
{"string", ExifInterface.TAG_SUBSEC_TIME_ORIGINAL},
|
||||
{"int", ExifInterface.TAG_SUBJECT_AREA},
|
||||
{"double", ExifInterface.TAG_SUBJECT_DISTANCE},
|
||||
{"int", ExifInterface.TAG_SUBJECT_DISTANCE_RANGE},
|
||||
{"int", ExifInterface.TAG_SUBJECT_LOCATION},
|
||||
{"string", ExifInterface.TAG_USER_COMMENT},
|
||||
{"int", ExifInterface.TAG_WHITE_BALANCE},
|
||||
{"int", ExifInterface.TAG_GPS_ALTITUDE_REF},
|
||||
{"string", ExifInterface.TAG_GPS_AREA_INFORMATION},
|
||||
{"double", ExifInterface.TAG_GPS_DOP},
|
||||
{"string", ExifInterface.TAG_GPS_DATESTAMP},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_BEARING},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_BEARING_REF},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_DISTANCE},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_DISTANCE_REF},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_LATITUDE},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_LATITUDE_REF},
|
||||
{"double", ExifInterface.TAG_GPS_DEST_LONGITUDE},
|
||||
{"string", ExifInterface.TAG_GPS_DEST_LONGITUDE_REF},
|
||||
{"int", ExifInterface.TAG_GPS_DIFFERENTIAL},
|
||||
{"double", ExifInterface.TAG_GPS_IMG_DIRECTION},
|
||||
{"string", ExifInterface.TAG_GPS_IMG_DIRECTION_REF},
|
||||
{"string", ExifInterface.TAG_GPS_LATITUDE_REF},
|
||||
{"string", ExifInterface.TAG_GPS_LONGITUDE_REF},
|
||||
{"string", ExifInterface.TAG_GPS_MAP_DATUM},
|
||||
{"string", ExifInterface.TAG_GPS_MEASURE_MODE},
|
||||
{"string", ExifInterface.TAG_GPS_PROCESSING_METHOD},
|
||||
{"string", ExifInterface.TAG_GPS_SATELLITES},
|
||||
{"double", ExifInterface.TAG_GPS_SPEED},
|
||||
{"string", ExifInterface.TAG_GPS_SPEED_REF},
|
||||
{"string", ExifInterface.TAG_GPS_STATUS},
|
||||
{"string", ExifInterface.TAG_GPS_TIMESTAMP},
|
||||
{"double", ExifInterface.TAG_GPS_TRACK},
|
||||
{"string", ExifInterface.TAG_GPS_TRACK_REF},
|
||||
{"string", ExifInterface.TAG_GPS_VERSION_ID},
|
||||
{"string", ExifInterface.TAG_INTEROPERABILITY_INDEX},
|
||||
{"int", ExifInterface.TAG_THUMBNAIL_IMAGE_LENGTH},
|
||||
{"int", ExifInterface.TAG_THUMBNAIL_IMAGE_WIDTH},
|
||||
{"int", ExifInterface.TAG_DNG_VERSION},
|
||||
{"int", ExifInterface.TAG_DEFAULT_CROP_SIZE},
|
||||
{"int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_START},
|
||||
{"int", ExifInterface.TAG_ORF_PREVIEW_IMAGE_LENGTH},
|
||||
{"int", ExifInterface.TAG_ORF_ASPECT_FRAME},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_BOTTOM_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_LEFT_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_RIGHT_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_SENSOR_TOP_BORDER},
|
||||
{"int", ExifInterface.TAG_RW2_ISO},
|
||||
};
|
||||
// Mount error event
|
||||
|
||||
@@ -187,7 +181,7 @@ public class RNCameraViewHelper {
|
||||
ViewGroup view,
|
||||
SparseArray<Face> faces,
|
||||
ImageDimensions dimensions
|
||||
) {
|
||||
) {
|
||||
float density = view.getResources().getDisplayMetrics().density;
|
||||
|
||||
double scaleX = (double) view.getWidth() / (dimensions.getWidth() * density);
|
||||
@@ -211,6 +205,27 @@ public class RNCameraViewHelper {
|
||||
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(event);
|
||||
}
|
||||
|
||||
// Barcode detection events
|
||||
|
||||
public static void emitBarcodesDetectedEvent(
|
||||
ViewGroup view,
|
||||
SparseArray<Barcode> barcodes
|
||||
) {
|
||||
BarcodesDetectedEvent event = BarcodesDetectedEvent.obtain(
|
||||
view.getId(),
|
||||
barcodes
|
||||
);
|
||||
|
||||
ReactContext reactContext = (ReactContext) view.getContext();
|
||||
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(event);
|
||||
}
|
||||
|
||||
public static void emitBarcodeDetectionErrorEvent(ViewGroup view, RNBarcodeDetector barcodeDetector) {
|
||||
BarcodeDetectionErrorEvent event = BarcodeDetectionErrorEvent.obtain(view.getId(), barcodeDetector);
|
||||
ReactContext reactContext = (ReactContext) view.getContext();
|
||||
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(event);
|
||||
}
|
||||
|
||||
// Bar code read event
|
||||
|
||||
public static void emitBarCodeReadEvent(ViewGroup view, Result barCode) {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.reactnative.camera.events;
|
||||
|
||||
import android.support.v4.util.Pools;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import org.reactnative.camera.CameraViewManager;
|
||||
import org.reactnative.barcodedetector.RNBarcodeDetector;
|
||||
|
||||
public class BarcodeDetectionErrorEvent extends Event<BarcodeDetectionErrorEvent> {
|
||||
|
||||
private static final Pools.SynchronizedPool<BarcodeDetectionErrorEvent> EVENTS_POOL = new Pools.SynchronizedPool<>(3);
|
||||
private RNBarcodeDetector mBarcodeDetector;
|
||||
|
||||
private BarcodeDetectionErrorEvent() {
|
||||
}
|
||||
|
||||
public static BarcodeDetectionErrorEvent obtain(int viewTag, RNBarcodeDetector barcodeDetector) {
|
||||
BarcodeDetectionErrorEvent event = EVENTS_POOL.acquire();
|
||||
if (event == null) {
|
||||
event = new BarcodeDetectionErrorEvent();
|
||||
}
|
||||
event.init(viewTag, barcodeDetector);
|
||||
return event;
|
||||
}
|
||||
|
||||
private void init(int viewTag, RNBarcodeDetector faceDetector) {
|
||||
super.init(viewTag);
|
||||
mBarcodeDetector = faceDetector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getCoalescingKey() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return CameraViewManager.Events.EVENT_ON_MOUNT_ERROR.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
|
||||
}
|
||||
|
||||
private WritableMap serializeEventData() {
|
||||
WritableMap map = Arguments.createMap();
|
||||
map.putBoolean("isOperational", mBarcodeDetector != null && mBarcodeDetector.isOperational());
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.reactnative.camera.events;
|
||||
|
||||
import android.support.v4.util.Pools;
|
||||
import android.util.SparseArray;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import org.reactnative.camera.CameraViewManager;
|
||||
import org.reactnative.barcodedetector.BarcodeFormatUtils;
|
||||
|
||||
public class BarcodesDetectedEvent extends Event<BarcodesDetectedEvent> {
|
||||
|
||||
private static final Pools.SynchronizedPool<BarcodesDetectedEvent> EVENTS_POOL =
|
||||
new Pools.SynchronizedPool<>(3);
|
||||
|
||||
private SparseArray<Barcode> mBarcodes;
|
||||
|
||||
private BarcodesDetectedEvent() {
|
||||
}
|
||||
|
||||
public static BarcodesDetectedEvent obtain(
|
||||
int viewTag,
|
||||
SparseArray<Barcode> barcodes
|
||||
) {
|
||||
BarcodesDetectedEvent event = EVENTS_POOL.acquire();
|
||||
if (event == null) {
|
||||
event = new BarcodesDetectedEvent();
|
||||
}
|
||||
event.init(viewTag, barcodes);
|
||||
return event;
|
||||
}
|
||||
|
||||
private void init(
|
||||
int viewTag,
|
||||
SparseArray<Barcode> barcodes
|
||||
) {
|
||||
super.init(viewTag);
|
||||
mBarcodes = barcodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* note(@sjchmiela)
|
||||
* Should the events about detected barcodes coalesce, the best strategy will be
|
||||
* to ensure that events with different barcodes count are always being transmitted.
|
||||
*/
|
||||
@Override
|
||||
public short getCoalescingKey() {
|
||||
if (mBarcodes.size() > Short.MAX_VALUE) {
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
|
||||
return (short) mBarcodes.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return CameraViewManager.Events.EVENT_ON_BARCODES_DETECTED.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
|
||||
}
|
||||
|
||||
private WritableMap serializeEventData() {
|
||||
WritableArray barcodesList = Arguments.createArray();
|
||||
|
||||
for (int i = 0; i < mBarcodes.size(); i++) {
|
||||
Barcode barcode = mBarcodes.valueAt(i);
|
||||
WritableMap serializedBarcode = Arguments.createMap();
|
||||
serializedBarcode.putString("data", barcode.displayValue);
|
||||
serializedBarcode.putString("type", BarcodeFormatUtils.get(barcode.format));
|
||||
barcodesList.pushMap(serializedBarcode);
|
||||
}
|
||||
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putString("type", "barcode");
|
||||
event.putArray("barcodes", barcodesList);
|
||||
event.putInt("target", getViewTag());
|
||||
return event;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,26 @@
|
||||
package org.reactnative.camera.events;
|
||||
|
||||
import android.support.v4.util.Pools;
|
||||
|
||||
import org.reactnative.camera.CameraViewManager;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
|
||||
import java.util.Date;
|
||||
import org.reactnative.camera.CameraViewManager;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
|
||||
public class FaceDetectionErrorEvent extends Event<FaceDetectionErrorEvent> {
|
||||
private static final Pools.SynchronizedPool<FaceDetectionErrorEvent> EVENTS_POOL = new Pools.SynchronizedPool<>(3);
|
||||
private RNFaceDetector mFaceDetector;
|
||||
private FaceDetectionErrorEvent() {}
|
||||
|
||||
private FaceDetectionErrorEvent() {
|
||||
}
|
||||
|
||||
public static FaceDetectionErrorEvent obtain(int viewTag, RNFaceDetector faceDetector) {
|
||||
FaceDetectionErrorEvent event = EVENTS_POOL.acquire();
|
||||
if (event == null) {
|
||||
event = new FaceDetectionErrorEvent();
|
||||
}
|
||||
event.init(viewTag);
|
||||
event.init(viewTag, faceDetector);
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -37,7 +36,7 @@ public class FaceDetectionErrorEvent extends Event<FaceDetectionErrorEvent> {
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return CameraViewManager.Events.EVENT_ON_MOUNT_ERROR.toString();
|
||||
return CameraViewManager.Events.EVENT_ON_FACE_DETECTION_ERROR.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,7 +46,7 @@ public class FaceDetectionErrorEvent extends Event<FaceDetectionErrorEvent> {
|
||||
|
||||
private WritableMap serializeEventData() {
|
||||
WritableMap map = Arguments.createMap();
|
||||
map.putBoolean("isOperational", mFaceDetector != null ? mFaceDetector.isOperational() : false);
|
||||
map.putBoolean("isOperational", mFaceDetector != null && mFaceDetector.isOperational());
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import com.google.android.cameraview.CameraView;
|
||||
import com.google.android.gms.vision.face.Face;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class FacesDetectedEvent extends Event<FacesDetectedEvent> {
|
||||
private static final Pools.SynchronizedPool<FacesDetectedEvent> EVENTS_POOL =
|
||||
new Pools.SynchronizedPool<>(3);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.reactnative.camera.tasks;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import org.reactnative.frame.RNFrame;
|
||||
import org.reactnative.frame.RNFrameFactory;
|
||||
import org.reactnative.barcodedetector.RNBarcodeDetector;
|
||||
|
||||
public class BarcodeDetectorAsyncTask extends android.os.AsyncTask<Void, Void, SparseArray<Barcode>> {
|
||||
|
||||
private byte[] mImageData;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private int mRotation;
|
||||
private RNBarcodeDetector mBarcodeDetector;
|
||||
private BarcodeDetectorAsyncTaskDelegate mDelegate;
|
||||
|
||||
public BarcodeDetectorAsyncTask(
|
||||
BarcodeDetectorAsyncTaskDelegate delegate,
|
||||
RNBarcodeDetector barcodeDetector,
|
||||
byte[] imageData,
|
||||
int width,
|
||||
int height,
|
||||
int rotation
|
||||
) {
|
||||
mImageData = imageData;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mRotation = rotation;
|
||||
mDelegate = delegate;
|
||||
mBarcodeDetector = barcodeDetector;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SparseArray<Barcode> doInBackground(Void... ignored) {
|
||||
if (isCancelled() || mDelegate == null || mBarcodeDetector == null || !mBarcodeDetector.isOperational()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RNFrame frame = RNFrameFactory.buildFrame(mImageData, mWidth, mHeight, mRotation);
|
||||
return mBarcodeDetector.detect(frame);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(SparseArray<Barcode> barcodes) {
|
||||
super.onPostExecute(barcodes);
|
||||
|
||||
if (barcodes == null) {
|
||||
mDelegate.onBarcodeDetectionError(mBarcodeDetector);
|
||||
} else {
|
||||
if (barcodes.size() > 0) {
|
||||
mDelegate.onBarcodesDetected(barcodes, mWidth, mHeight, mRotation);
|
||||
}
|
||||
mDelegate.onBarcodeDetectingTaskCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package org.reactnative.camera.tasks;
|
||||
|
||||
import android.util.SparseArray;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import org.reactnative.barcodedetector.RNBarcodeDetector;
|
||||
|
||||
public interface BarcodeDetectorAsyncTaskDelegate {
|
||||
|
||||
void onBarcodesDetected(SparseArray<Barcode> barcodes, int sourceWidth, int sourceHeight, int sourceRotation);
|
||||
|
||||
void onBarcodeDetectionError(RNBarcodeDetector barcodeDetector);
|
||||
|
||||
void onBarcodeDetectingTaskCompleted();
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
package org.reactnative.camera.tasks;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
import org.reactnative.facedetector.RNFrame;
|
||||
import org.reactnative.facedetector.RNFrameFactory;
|
||||
import com.google.android.gms.vision.face.Face;
|
||||
import org.reactnative.frame.RNFrame;
|
||||
import org.reactnative.frame.RNFrameFactory;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
|
||||
public class FaceDetectorAsyncTask extends android.os.AsyncTask<Void, Void, SparseArray<Face>> {
|
||||
private byte[] mImageData;
|
||||
@@ -48,7 +47,9 @@ public class FaceDetectorAsyncTask extends android.os.AsyncTask<Void, Void, Spar
|
||||
if (faces == null) {
|
||||
mDelegate.onFaceDetectionError(mFaceDetector);
|
||||
} else {
|
||||
mDelegate.onFacesDetected(faces, mWidth, mHeight, mRotation);
|
||||
if (faces.size() > 0) {
|
||||
mDelegate.onFacesDetected(faces, mWidth, mHeight, mRotation);
|
||||
}
|
||||
mDelegate.onFaceDetectingTaskCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import android.util.SparseArray;
|
||||
|
||||
import com.google.android.gms.vision.text.TextBlock;
|
||||
import com.google.android.gms.vision.text.TextRecognizer;
|
||||
import org.reactnative.facedetector.RNFrame;
|
||||
import org.reactnative.facedetector.RNFrameFactory;
|
||||
import org.reactnative.frame.RNFrame;
|
||||
import org.reactnative.frame.RNFrameFactory;
|
||||
|
||||
|
||||
public class TextRecognizerAsyncTask extends android.os.AsyncTask<Void, Void, SparseArray<TextBlock>> {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.reactnative.facedetector;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.reactnative.facedetector.tasks.FileFaceDetectionAsyncTask;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package org.reactnative.facedetector;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.reactnative.camera.utils.ImageDimensions;
|
||||
import com.google.android.gms.vision.face.Face;
|
||||
import com.google.android.gms.vision.face.FaceDetector;
|
||||
import org.reactnative.frame.RNFrame;
|
||||
|
||||
public class RNFaceDetector {
|
||||
public static int ALL_CLASSIFICATIONS = FaceDetector.ALL_CLASSIFICATIONS;
|
||||
|
||||
+2
-5
@@ -10,21 +10,18 @@ import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
import org.reactnative.facedetector.RNFrame;
|
||||
import org.reactnative.facedetector.RNFrameFactory;
|
||||
import org.reactnative.frame.RNFrame;
|
||||
import org.reactnative.frame.RNFrameFactory;
|
||||
import org.reactnative.facedetector.FaceDetectorUtils;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.google.android.gms.vision.Frame;
|
||||
import com.google.android.gms.vision.face.Face;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
|
||||
public class FileFaceDetectionAsyncTask extends AsyncTask<Void, Void, SparseArray<Face>> {
|
||||
private static final String ERROR_TAG = "E_FACE_DETECTION_FAILED";
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package org.reactnative.facedetector;
|
||||
package org.reactnative.frame;
|
||||
|
||||
import org.reactnative.camera.utils.ImageDimensions;
|
||||
import com.google.android.gms.vision.Frame;
|
||||
|
||||
/**
|
||||
* Wrapper around Frame allowing us to track Frame dimensions.
|
||||
* Tracking dimensions is used in RNFaceDetector to provide painless FaceDetector recreation
|
||||
* Tracking dimensions is used in RNFaceDetector and RNBarcodeDetector to provide painless FaceDetector/BarcodeDetector recreation
|
||||
* when image dimensions change.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.reactnative.facedetector;
|
||||
package org.reactnative.frame;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.ImageFormat;
|
||||
Reference in New Issue
Block a user