package com.mlkit; import android.graphics.Rect; import android.support.annotation.NonNull; import android.util.Log; 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.WritableArray; import com.facebook.react.bridge.WritableMap; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; import com.google.firebase.ml.vision.FirebaseVision; import com.google.firebase.ml.vision.common.FirebaseVisionPoint; import com.google.firebase.ml.vision.face.FirebaseVisionFace; import com.google.firebase.ml.vision.face.FirebaseVisionFaceContour; import com.google.firebase.ml.vision.face.FirebaseVisionFaceDetector; import com.google.firebase.ml.vision.face.FirebaseVisionFaceDetectorOptions; import com.google.firebase.ml.vision.text.FirebaseVisionCloudTextRecognizerOptions; import com.google.firebase.ml.vision.common.FirebaseVisionImage; import com.google.firebase.ml.vision.text.FirebaseVisionText; import com.google.firebase.ml.vision.text.FirebaseVisionTextRecognizer; import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcode; import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetector; import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetectorOptions; import java.io.IOException; import java.util.List; import java.util.ArrayList; public class RNMlKitModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; private FirebaseVisionTextRecognizer textDetector; private FirebaseVisionTextRecognizer cloudTextDetector; private FirebaseVisionFaceDetector faceDetector; public RNMlKitModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; } @ReactMethod public void deviceBarcodeRecognition(String uri, final Promise promise) { try { FirebaseVisionBarcodeDetectorOptions options = new FirebaseVisionBarcodeDetectorOptions.Builder() .setBarcodeFormats(FirebaseVisionBarcode. FORMAT_ALL_FORMATS) .build(); FirebaseVisionImage image = FirebaseVisionImage.fromFilePath(this.reactContext, android.net.Uri.parse(uri)); FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance() .getVisionBarcodeDetector(options); Task<List<FirebaseVisionBarcode>> result = detector.detectInImage(image) .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionBarcode>>() { @Override public void onSuccess(List<FirebaseVisionBarcode> barcodes) { WritableArray data = Arguments.createArray(); WritableMap info = Arguments.createMap(); for (FirebaseVisionBarcode barcode: barcodes) { info = Arguments.createMap(); info.putString("format", barcodeFormat(barcode.getFormat())); info.putString("value", barcode.getRawValue()); data.pushMap(info); } promise.resolve(data); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { e.printStackTrace(); promise.reject(e); } }); } catch (IOException e) { promise.reject(e); e.printStackTrace(); } } @ReactMethod public void deviceTextRecognition(String uri, final Promise promise) { try { FirebaseVisionImage image = FirebaseVisionImage.fromFilePath(this.reactContext, android.net.Uri.parse(uri)); FirebaseVisionTextRecognizer detector = this.getTextRecognizerInstance(); Task<FirebaseVisionText> result = detector.processImage(image) .addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() { @Override public void onSuccess(FirebaseVisionText firebaseVisionText) { promise.resolve(processDeviceResult(firebaseVisionText)); } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { e.printStackTrace(); promise.reject(e); } });; } catch (IOException e) { promise.reject(e); e.printStackTrace(); } } @ReactMethod public void deviceFaceRecognition(String uri, final Promise promise){ try{ FirebaseVisionImage image = FirebaseVisionImage.fromFilePath(this.reactContext, android.net.Uri.parse(uri)); FirebaseVisionFaceDetector detector = this.getFaceDetectorInstance(); Task<List<FirebaseVisionFace>> result = detector.detectInImage(image) .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() { @Override public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) { promise.resolve(processFaceDetectionResult(firebaseVisionFaces)); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { e.printStackTrace(); promise.reject(e); } }); }catch (Exception e){ promise.reject(e); e.printStackTrace(); } } private FirebaseVisionTextRecognizer getTextRecognizerInstance() { if (this.textDetector == null) { this.textDetector = FirebaseVision.getInstance().getOnDeviceTextRecognizer(); } return this.textDetector; } private FirebaseVisionFaceDetector getFaceDetectorInstance(){ if(this.faceDetector == null){ //=====Set options===== FirebaseVisionFaceDetectorOptions options = new FirebaseVisionFaceDetectorOptions.Builder() .setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS) .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS) .setContourMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS) .setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS) .setMinFaceSize(0.15f) .enableTracking() .build(); //===================== this.faceDetector = FirebaseVision.getInstance().getVisionFaceDetector(options); } return this.faceDetector; } @ReactMethod public void close(final Promise promise) { if(this.textDetector != null) { try { this.textDetector.close(); this.textDetector = null; promise.resolve(true); } catch (IOException e) { e.printStackTrace(); promise.reject(e); } } if(this.cloudTextDetector != null) { try { this.cloudTextDetector.close(); this.cloudTextDetector = null; promise.resolve(true); } catch (IOException e) { e.printStackTrace(); promise.reject(e); } } if(this.faceDetector != null) { try { this.faceDetector.close(); this.faceDetector = null; promise.resolve(true); } catch (IOException e) { e.printStackTrace(); promise.reject(e); } } } private FirebaseVisionTextRecognizer getCloudTextRecognizerInstance() { if (this.cloudTextDetector == null) { this.cloudTextDetector = FirebaseVision.getInstance().getCloudTextRecognizer(); } return this.cloudTextDetector; } @ReactMethod public void cloudTextRecognition(String uri, final Promise promise) { try { FirebaseVisionTextRecognizer detector = this.getCloudTextRecognizerInstance(); FirebaseVisionImage image = FirebaseVisionImage.fromFilePath(this.reactContext, android.net.Uri.parse(uri)); Task<FirebaseVisionText> result = detector.processImage(image) .addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() { @Override public void onSuccess(FirebaseVisionText firebaseVisionText) { promise.resolve(processCloudResult(firebaseVisionText)); } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { e.printStackTrace(); promise.reject(e); } }); } catch (IOException e) { promise.reject(e); e.printStackTrace(); } } private String barcodeFormat(int format) { switch (format) { case FirebaseVisionBarcode.FORMAT_CODE_128: return "CODE_128"; case FirebaseVisionBarcode.FORMAT_CODE_39: return "CODE_39"; case FirebaseVisionBarcode.FORMAT_CODE_93: return "CODE_93"; case FirebaseVisionBarcode.FORMAT_CODABAR: return "CODABAR"; case FirebaseVisionBarcode.FORMAT_DATA_MATRIX: return "DATA_MATRIX"; case FirebaseVisionBarcode.FORMAT_EAN_13: return "EAN_13"; case FirebaseVisionBarcode.FORMAT_EAN_8: return "EAN_8"; case FirebaseVisionBarcode.FORMAT_ITF: return "ITF"; case FirebaseVisionBarcode.FORMAT_QR_CODE: return "QR_CODE"; case FirebaseVisionBarcode.FORMAT_UPC_A: return "UPC_A"; case FirebaseVisionBarcode.FORMAT_UPC_E: return "UPC_E"; case FirebaseVisionBarcode.FORMAT_PDF417: return "PDF417"; case FirebaseVisionBarcode.FORMAT_AZTEC: return "AZTEC"; default: return "UNKNOWN"; } } /** * Converts firebaseVisionText into a map * * @param firebaseVisionText * @return */ private WritableArray processDeviceResult(FirebaseVisionText firebaseVisionText) { WritableArray data = Arguments.createArray(); WritableMap info = Arguments.createMap(); WritableMap coordinates = Arguments.createMap(); List<FirebaseVisionText.TextBlock> blocks = firebaseVisionText.getTextBlocks(); if (blocks.size() == 0) { return data; } for (int i = 0; i < blocks.size(); i++) { List<FirebaseVisionText.Line> lines = blocks.get(i).getLines(); info = Arguments.createMap(); coordinates = Arguments.createMap(); Rect boundingBox = blocks.get(i).getBoundingBox(); coordinates.putInt("top", boundingBox.top); coordinates.putInt("left", boundingBox.left); coordinates.putInt("width", boundingBox.width()); coordinates.putInt("height", boundingBox.height()); info.putMap("blockCoordinates", coordinates); info.putString("blockText", blocks.get(i).getText()); info.putString("resultText", firebaseVisionText.getText()); for (int j = 0; j < lines.size(); j++) { List<FirebaseVisionText.Element> elements = lines.get(j).getElements(); info.putString("lineText", lines.get(j).getText()); for (int k = 0; k < elements.size(); k++) { info.putString("elementText", elements.get(k).getText()); } } data.pushMap(info); } return data; } private WritableArray processCloudResult(FirebaseVisionText firebaseVisionText) { WritableArray data = Arguments.createArray(); WritableMap info = Arguments.createMap(); WritableMap coordinates = Arguments.createMap(); List<FirebaseVisionText.TextBlock> blocks = firebaseVisionText.getTextBlocks(); if (blocks.size() == 0) { return data; } for (int i = 0; i < blocks.size(); i++) { List<FirebaseVisionText.Line> lines = blocks.get(i).getLines(); info = Arguments.createMap(); coordinates = Arguments.createMap(); Rect boundingBox = blocks.get(i).getBoundingBox(); coordinates.putInt("top", boundingBox.top); coordinates.putInt("left", boundingBox.left); coordinates.putInt("width", boundingBox.width()); coordinates.putInt("height", boundingBox.height()); info.putMap("blockCoordinates", coordinates); info.putString("blockText", blocks.get(i).getText()); for (int j = 0; j < lines.size(); j++) { List<FirebaseVisionText.Element> elements = lines.get(j).getElements(); info.putString("lineText", lines.get(j).getText()); for (int k = 0; k < elements.size(); k++) { info.putString("elementText", elements.get(k).getText()); } } data.pushMap(info); } return data; } private WritableArray processFaceDetectionResult(List<FirebaseVisionFace> firebaseVisionFaces){ WritableArray data = Arguments.createArray(); if(firebaseVisionFaces.size() > 0){ WritableMap info = Arguments.createMap(); for (FirebaseVisionFace face : firebaseVisionFaces){ info = Arguments.createMap(); //face bounding box Rect faceBounding = face.getBoundingBox(); WritableMap faceBox = Arguments.createMap(); faceBox.putInt("top", faceBounding.top); faceBox.putInt("right", faceBounding.right); faceBox.putInt("bottom", faceBounding.bottom); faceBox.putInt("left", faceBounding.left); info.putMap("faceBoundingRect", faceBox); // If classification was enabled: if (face.getSmilingProbability() != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) { float smileProb = face.getSmilingProbability(); info.putDouble("smileProbability", (double)smileProb); } if (face.getRightEyeOpenProbability() != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) { float rightEyeOpenProb = face.getRightEyeOpenProbability(); info.putDouble("rightEyeOpenProbability", (double)rightEyeOpenProb); } // If face tracking was enabled: if (face.getTrackingId() != FirebaseVisionFace.INVALID_ID) { int id = face.getTrackingId(); info.putInt("faceTrackingId", id); } //eyes info.putArray("leftEyeContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.LEFT_EYE)); info.putArray("rightEyeContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.RIGHT_EYE)); //face info.putArray("faceContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.FACE)); //lower lip info.putArray("lowerLipBottomContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.LOWER_LIP_BOTTOM)); info.putArray("lowerLipBottomContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.LOWER_LIP_TOP)); //upper lip info.putArray("upperLipTopContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.UPPER_LIP_TOP)); info.putArray("upperLipBottomContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.UPPER_LIP_BOTTOM)); //nose info.putArray("noiseBottomContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.NOSE_BOTTOM)); info.putArray("noiseBridgeContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.NOSE_BRIDGE)); //left eyebrow info.putArray("leftEyeBrowBottomContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.LEFT_EYEBROW_BOTTOM)); info.putArray("leftEyeBrowTopContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.LEFT_EYEBROW_TOP)); // right eyebrow info.putArray("rightEyeBrowBottomContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.RIGHT_EYEBROW_BOTTOM)); info.putArray("rightEyeBrowTopContourPoints", Utils.getContourPointsWritableArray(face, FirebaseVisionFaceContour.RIGHT_EYEBROW_TOP)); data.pushMap(info); } } return data; } @Override public String getName() { return "RNMlKit"; } }