Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit a79d05e

Browse files
#699 Add ML Kit support (iOS camera stream)
1 parent ebdb66a commit a79d05e

30 files changed

+833
-27
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package-lock.json
77
build/
88
*.log.*
99
src/**/*.d.ts
10+
src/platforms/ios_lib/TNSMLKitCamera/TNSMLKitCamera.xcodeproj/project.xcworkspace
11+
src/platforms/ios_lib/TNSMLKitCamera/TNSMLKitCamera.xcodeproj/xcuserdata
1012
src/platforms/ios/Podfile
1113
src/platforms/ios/build.xcconfig
1214
src/platforms/android/include.gradle

demo-ng/app/app.module.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import { AppComponent } from "./app.component";
55

66
import { ItemsComponent } from "./item/items.component";
77

8+
import { registerElement } from "nativescript-angular/element-registry";
9+
10+
registerElement("MLKitBarcodeScanner", () => require("nativescript-plugin-firebase/mlkit/barcodescanning").MLKitBarcodeScanner);
11+
// registerElement("MLKitFaceRecognition", () => require("nativescript-plugin-firebase/mlkit/facedetection").MLKitFaceRecognition);
12+
// registerElement("MLKitTextRecognition", () => require("nativescript-plugin-firebase/mlkit/textrecognition").MLKitTextRecognition);
13+
814
@NgModule({
915
bootstrap: [
1016
AppComponent

demo-ng/app/item/items.component.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
<StackLayout class="page">
66
<Label text="After pressing those buttons, check the console log" textWrap="true"></Label>
77

8+
<MLKitBarcodeScanner
9+
width="400"
10+
height="300"
11+
formats="QR_CODE, EAN_8"
12+
(scanResult)="onBarcodeScanResult($event)">
13+
</MLKitBarcodeScanner>
14+
815
<Label text="Authentication" class="h2"></Label>
916
<Button text="login anonymously" (tap)="loginAnonymously()" class="button button-user"></Button>
1017

demo-ng/app/item/items.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Component, NgZone } from "@angular/core";
22
import { firestore } from "nativescript-plugin-firebase";
33
import { Observable } from "rxjs/Observable";
44
import { City } from "../model/City";
5+
import { MLKitScanBarcodesResult } from "../../../src/mlkit/barcodescanning";
56

67
const firebase = require("nativescript-plugin-firebase/app");
78
const firebaseWebApi = require("nativescript-plugin-firebase/app");
@@ -26,6 +27,11 @@ export class ItemsComponent {
2627
// AngularFireModule.initializeApp({});
2728
}
2829

30+
onBarcodeScanResult(event): void {
31+
const result: MLKitScanBarcodesResult = event.value;
32+
console.log("Received barcode(s): " + JSON.stringify(result));
33+
}
34+
2935
public loginAnonymously(): void {
3036
firebase.auth().signInAnonymously()
3137
.then(() => console.log("Logged in"))

src/.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ tsconfig.json
55
references.d.ts
66
platforms/android/libraryproject/
77
platforms/ios/typings/
8+
platforms/ios_lib/
89
platforms/android/typings/
910
platforms/web
1011
platforms/ios/Podfile

src/mlkit/barcodescanning/index.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { MLKitOptions } from "../";
22
import { BarcodeFormat } from "./barcodescanning-common";
33
import { MLKitResult, MLKitCameraView } from "../index";
44

5-
export declare const BarcodeFormat: typeof BarcodeFormat;
6-
75
export interface MLKitScanBarcodesResult extends MLKitResult {
86
barcodes: Array<{
97
value: string;

src/mlkit/barcodescanning/index.ios.ts

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,68 @@
11
import { ImageSource } from "tns-core-modules/image-source";
2-
import { BarcodeFormat } from "./barcodescanning-common";
3-
import { MLKitCameraView as MLKitBarcodeScannerBase } from "../mlkit-cameraview";
42
import { MLKitScanBarcodesOptions, MLKitScanBarcodesResult } from "./index";
53
import { MLKitOptions } from "../index";
4+
import { BarcodeFormat, MLKitBarcodeScanner as MLKitBarcodeScannerBase } from "./barcodescanning-common";
65

76
export { BarcodeFormat };
87

98
export class MLKitBarcodeScanner extends MLKitBarcodeScannerBase {
10-
119
protected createDetector(): any {
12-
}
13-
14-
protected createFailureListener(): any {
10+
let formats: Array<BarcodeFormat>;
11+
if (this.formats) {
12+
formats = [];
13+
const requestedFormats = this.formats.split(",");
14+
requestedFormats.forEach(format => formats.push(BarcodeFormat[format.trim().toUpperCase()]))
15+
}
16+
return getBarcodeDetector(formats);
1517
}
1618

1719
protected createSuccessListener(): any {
20+
return (barcodes: NSArray<FIRVisionBarcode>, error: NSError) => {
21+
if (error !== null) {
22+
console.log(error.localizedDescription);
23+
24+
} else if (barcodes !== null) {
25+
const result = <MLKitScanBarcodesResult>{
26+
barcodes: []
27+
};
28+
29+
for (let i = 0, l = barcodes.count; i < l; i++) {
30+
const barcode: FIRVisionBarcode = barcodes.objectAtIndex(i);
31+
result.barcodes.push({
32+
value: barcode.rawValue,
33+
format: BarcodeFormat[barcode.format]
34+
});
35+
}
36+
37+
this.notify({
38+
eventName: MLKitBarcodeScanner.scanResultEvent,
39+
object: this,
40+
value: result
41+
});
42+
}
43+
}
1844
}
45+
}
1946

20-
// public onLayout(left: number, top: number, right: number, bottom: number): void {
21-
// super.onLayout(left, top, right, bottom);
22-
// if (this._hasSupport && this.ios) {
23-
// this._reader.previewLayer.frame = this.ios.layer.bounds;
24-
// }
25-
// }
47+
function getBarcodeDetector(formats?: Array<BarcodeFormat>): any {
48+
if (formats && formats.length > 0) {
49+
// TODO
50+
const barcodeDetector: FIRVisionBarcodeDetector = FIRVision.vision().barcodeDetector();
51+
return barcodeDetector;
52+
// const firebaseVisionBarcodeDetectorOptions =
53+
// new com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetectorOptions.Builder()
54+
// .setBarcodeFormats(formats[0], formats) // the seconds argument is a varargs.. let's make it easy and just do it like this
55+
// .build();
56+
// return com.google.firebase.ml.vision.FirebaseVision.getInstance().getVisionBarcodeDetector(firebaseVisionBarcodeDetectorOptions);
57+
} else {
58+
return FIRVision.vision().barcodeDetector();
59+
}
2660
}
2761

2862
export function scanBarcodes(options: MLKitScanBarcodesOptions): Promise<MLKitScanBarcodesResult> {
2963
return new Promise((resolve, reject) => {
3064
try {
31-
const firVision: FIRVision = FIRVision.vision();
32-
// TODO pass in formats
33-
const barcodeDetector: FIRVisionBarcodeDetector = firVision.barcodeDetector();
34-
// const textDetector: FIRVisionBarcodeDetector = firVision.barcodeDetectorWithOptions();
65+
const barcodeDetector = getBarcodeDetector(options.formats);
3566

3667
barcodeDetector.detectInImageCompletion(getImage(options), (barcodes: NSArray<FIRVisionBarcode>, error: NSError) => {
3768
if (error !== null) {

src/mlkit/facedetection/index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { MLKitOptions } from "../";
2-
import { BarcodeFormat } from "./barcodescanning-common";
32
import { MLKitCameraView, MLKitResult } from "../index";
43

54
export interface MLKitDetectFacesResult extends MLKitResult {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { ImageSource } from "tns-core-modules/image-source";
2+
import { MLKitDetectFacesOptions, MLKitDetectFacesResult } from "./";
3+
import { MLKitOptions } from "../index";
4+
5+
// export class MLKitFaceDetection extends MLKitFaceDetectionBase {
6+
// constructor() {
7+
// super();
8+
// console.log(">>> MLKitFaceDetection constr");
9+
// }
10+
// }
11+
12+
export function detectFaces(options: MLKitDetectFacesOptions): Promise<MLKitDetectFacesResult> {
13+
return new Promise((resolve, reject) => {
14+
try {
15+
const firVision: FIRVision = FIRVision.vision();
16+
const faceDetector: FIRVisionFaceDetector = firVision.faceDetector();
17+
18+
faceDetector.detectInImageCompletion(getImage(options), (faces: NSArray<FIRVisionFace>, error: NSError) => {
19+
if (error !== null) {
20+
reject(error.localizedDescription);
21+
22+
} else if (faces !== null) {
23+
const result = <MLKitDetectFacesResult>{
24+
faces: []
25+
};
26+
27+
for (let i = 0, l = faces.count; i < l; i++) {
28+
const face: FIRVisionFace = faces.objectAtIndex(i);
29+
result.faces.push({
30+
smilingProbability: face.hasSmilingProbability ? face.smilingProbability : undefined,
31+
leftEyeOpenProbability: face.hasLeftEyeOpenProbability ? face.leftEyeOpenProbability : undefined,
32+
rightEyeOpenProbability: face.hasRightEyeOpenProbability ? face.rightEyeOpenProbability : undefined
33+
});
34+
}
35+
resolve(result);
36+
}
37+
});
38+
} catch (ex) {
39+
console.log("Error in firebase.mlkit.detectFaces: " + ex);
40+
reject(ex);
41+
}
42+
});
43+
}
44+
45+
// TODO move
46+
function getImage(options: MLKitOptions): FIRVisionImage {
47+
const image: UIImage = options.image instanceof ImageSource ? options.image.ios : options.image.imageSource.ios;
48+
return FIRVisionImage.alloc().initWithImage(image);
49+
}

src/mlkit/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ export interface MLKitResult {
2020
imageSource?: ImageSource;
2121
}
2222

23+
export declare class MLKitCameraView {
24+
}
25+
2326
export declare class MLKitBarcodeScanner {
2427
}
2528

0 commit comments

Comments
 (0)