Add GoogleVision barcode scanner.

This commit is contained in:
Serhii Avsheniuk
2018-04-10 23:32:11 +02:00
parent e0e1c47273
commit 8f72ef949f
22 changed files with 648 additions and 224 deletions
@@ -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();
}
}
}
@@ -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;
@@ -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";
@@ -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,4 +1,4 @@
package org.reactnative.facedetector;
package org.reactnative.frame;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;