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

Commit 5d9133d

Browse files
#699 Add ML Kit support (Add a 'bounds' property so you know where in the image text was found)
1 parent a3a3006 commit 5d9133d

File tree

6 files changed

+120
-93
lines changed

6 files changed

+120
-93
lines changed

demo-ng/app/tabs/mlkit/mlkit.component.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class MLKitComponent {
2424

2525
pickedImage: ImageSource;
2626

27+
// TODO once more ML plugin features support cloud, add those as (cloud) options to this list
2728
private mlkitFeatures: Array<string> = [
2829
"Text recognition",
2930
"Barcode scanning",
@@ -113,7 +114,11 @@ export class MLKitComponent {
113114
return;
114115
}
115116
if (!image) {
116-
console.log(`This is probably an iCloud image - which won't work`);
117+
alert({
118+
title: `Invalid image`,
119+
message: `Perhaps this is an image from cloud storage?`,
120+
okButtonText: "Hmm.."
121+
});
117122
return;
118123
}
119124
const imageSource = new ImageSource();
@@ -158,7 +163,7 @@ export class MLKitComponent {
158163
(result: MLKitRecognizeTextResult) => {
159164
alert({
160165
title: `Result`,
161-
message: JSON.stringify(result.features),
166+
message: result.features.map(feature => feature.text).join(""),
162167
okButtonText: "OK"
163168
});
164169
})

publish/publish.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ PACK_DIR=package;
55
publish() {
66
cd $PACK_DIR
77
echo 'Publishing to npm...'
8+
# npm publish *.tgz --tag next
89
npm publish *.tgz
910
}
1011

11-
./pack.sh && publish
12+
./pack.sh && publish

src/mlkit/textrecognition/index.android.ts

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ImageSource } from "tns-core-modules/image-source";
22
import { MLKitOptions, } from "../";
33
import { MLKitRecognizeTextOptions, MLKitRecognizeTextResult } from "./";
44
import { MLKitTextRecognition as MLKitTextRecognitionBase } from "./textrecognition-common";
5+
import { MLKitRecognizeTextResultFeature } from "./index";
56

67
declare const com: any;
78

@@ -14,58 +15,67 @@ export class MLKitTextRecognition extends MLKitTextRecognitionBase {
1415
protected createSuccessListener(): any {
1516
return new com.google.android.gms.tasks.OnSuccessListener({
1617
onSuccess: textBlocks => {
17-
18-
if (textBlocks.getBlocks().size() === 0) return;
19-
20-
const blocks = textBlocks.getBlocks();
21-
22-
// const imageSource = new ImageSource();
23-
// imageSource.setNativeSource(this.lastVisionImage.getBitmapForDebugging());
24-
25-
const result = <MLKitRecognizeTextResult>{
26-
features: []
27-
};
28-
29-
// see https://github.com/firebase/quickstart-android/blob/0f4c86877fc5f771cac95797dffa8bd026dd9dc7/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/textrecognition/TextRecognitionProcessor.java#L62
30-
for (let i = 0; i < blocks.size(); i++) {
31-
const textBlock = blocks.get(i);
32-
result.features.push({
33-
text: textBlock.getText()
18+
if (textBlocks.getBlocks().size() > 0) {
19+
this.notify({
20+
eventName: MLKitTextRecognition.scanResultEvent,
21+
object: this,
22+
value: getResult(textBlocks.getBlocks())
3423
});
3524
}
36-
37-
this.notify({
38-
eventName: MLKitTextRecognition.scanResultEvent,
39-
object: this,
40-
value: result
41-
});
4225
}
4326
});
4427
}
4528
}
4629

30+
function getResult(blocks: any): MLKitRecognizeTextResult {
31+
const result = <MLKitRecognizeTextResult>{
32+
features: []
33+
};
34+
35+
// see https://github.com/firebase/quickstart-android/blob/0f4c86877fc5f771cac95797dffa8bd026dd9dc7/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/textrecognition/TextRecognitionProcessor.java#L62
36+
for (let i = 0; i < blocks.size(); i++) {
37+
const textBlock = blocks.get(i);
38+
const blockResult = <MLKitRecognizeTextResultFeature>{
39+
text: textBlock.getText(),
40+
elements: []
41+
};
42+
43+
const lines = textBlock.getLines();
44+
for (let j = 0; j < lines.size(); j++) {
45+
const elements = lines.get(j).getElements();
46+
for (let k = 0; k < elements.size(); k++) {
47+
const element = elements.get(k);
48+
const rect = element.getBoundingBox();
49+
const blockElement = {
50+
text: element.getText(),
51+
bounds: {
52+
origin: {
53+
x: rect.left,
54+
y: rect.top
55+
},
56+
size: {
57+
width: rect.width(),
58+
height: rect.height()
59+
}
60+
}
61+
};
62+
blockResult.elements.push(blockElement);
63+
}
64+
}
65+
66+
result.features.push(blockResult);
67+
}
68+
return result;
69+
}
70+
4771
export function recognizeText(options: MLKitRecognizeTextOptions): Promise<MLKitRecognizeTextResult> {
4872
return new Promise((resolve, reject) => {
4973
try {
5074
const firebaseVisionTextDetector = com.google.firebase.ml.vision.FirebaseVision.getInstance().getVisionTextDetector();
5175

5276
const onSuccessListener = new com.google.android.gms.tasks.OnSuccessListener({
5377
onSuccess: textBlocks => {
54-
const blocks = textBlocks.getBlocks();
55-
56-
const result = <MLKitRecognizeTextResult>{
57-
features: []
58-
};
59-
60-
// see https://github.com/firebase/quickstart-android/blob/0f4c86877fc5f771cac95797dffa8bd026dd9dc7/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/textrecognition/TextRecognitionProcessor.java#L62
61-
for (let i = 0; i < blocks.size(); i++) {
62-
const textBlock = blocks.get(i);
63-
result.features.push({
64-
text: textBlock.getText()
65-
});
66-
}
67-
68-
resolve(result);
78+
resolve(getResult(textBlocks.getBlocks()));
6979
firebaseVisionTextDetector.close();
7080
}
7181
});

src/mlkit/textrecognition/index.d.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
import { MLKitMultiEngineOptions } from "../";
22
import { MLKitCameraView, MLKitResult } from "../index";
33

4-
export interface MLKitRecognizeTextResult extends MLKitResult {
5-
features: Array<{
4+
export interface MLKitRecognizeTextResultFeature {
5+
text: string;
6+
elements: Array<{
67
text: string;
7-
// corners: any;
8-
}>;
8+
bounds: {
9+
origin: {
10+
x: number;
11+
y: number;
12+
},
13+
size: {
14+
width: number;
15+
height: number;
16+
}
17+
};
18+
}>
19+
}
20+
21+
export interface MLKitRecognizeTextResult extends MLKitResult {
22+
features: Array<MLKitRecognizeTextResultFeature>;
923
}
1024

1125
export interface MLKitRecognizeTextOptions extends MLKitMultiEngineOptions {

src/mlkit/textrecognition/index.ios.ts

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ImageSource } from "tns-core-modules/image-source";
22
import { MLKitOptions } from "../";
33
import { MLKitRecognizeTextOptions, MLKitRecognizeTextResult } from "./";
44
import { MLKitTextRecognition as MLKitTextRecognitionBase } from "./textrecognition-common";
5+
import { MLKitRecognizeTextResultFeature } from "./index";
56

67
export class MLKitTextRecognition extends MLKitTextRecognitionBase {
78
protected createDetector(): any {
@@ -13,46 +14,14 @@ export class MLKitTextRecognition extends MLKitTextRecognitionBase {
1314
return (features: NSArray<FIRVisionText>, error: NSError) => {
1415
if (error !== null) {
1516
console.log(error.localizedDescription);
16-
1717
} else if (features !== null && features.count > 0) {
18-
const result = <MLKitRecognizeTextResult>{
19-
features: []
20-
};
21-
22-
for (let i = 0, l = features.count; i < l; i++) {
23-
const feature: FIRVisionText = features.objectAtIndex(i);
24-
// Note that fetching these details works, but there's currently no added value
25-
/*
26-
if (feature instanceof FIRVisionTextBlock) {
27-
const textBlock = <FIRVisionTextBlock>feature;
28-
for (let j = 0, k = textBlock.lines.count; j < k; j++) {
29-
const textBlockLine: FIRVisionTextLine = textBlock.lines.objectAtIndex(j);
30-
for (let a = 0, m = textBlockLine.elements.count; a < m; a++) {
31-
const element: FIRVisionTextElement = textBlockLine.elements.objectAtIndex(a);
32-
console.log("FIRVisionTextBlock text: " + element.text);
33-
}
34-
}
35-
}
36-
if (feature instanceof FIRVisionTextLine) {
37-
for (let a = 0, m = feature.elements.count; a < m; a++) {
38-
const element: FIRVisionTextElement = feature.elements.objectAtIndex(a);
39-
console.log("FIRVisionTextLine text: " + element.text);
40-
}
41-
}
42-
*/
43-
result.features.push({
44-
text: feature.text,
45-
// corners: this.getCorners(<any>feature.cornerPoints)
46-
});
47-
}
48-
4918
this.notify({
5019
eventName: MLKitTextRecognition.scanResultEvent,
5120
object: this,
52-
value: result
21+
value: getResult(features)
5322
});
5423
}
55-
}
24+
};
5625
}
5726

5827
protected rotateRecording(): boolean {
@@ -70,6 +39,46 @@ export class MLKitTextRecognition extends MLKitTextRecognitionBase {
7039
*/
7140
}
7241

42+
function getResult(features: NSArray<FIRVisionText>): MLKitRecognizeTextResult {
43+
const result = <MLKitRecognizeTextResult>{
44+
features: []
45+
};
46+
47+
for (let i = 0, l = features.count; i < l; i++) {
48+
const feature = features.objectAtIndex(i);
49+
const resultFeature = <MLKitRecognizeTextResultFeature>{
50+
text: feature.text,
51+
elements: []
52+
};
53+
54+
const addLineToResult = (line: FIRVisionTextLine): void => {
55+
for (let a = 0, m = line.elements.count; a < m; a++) {
56+
const element: FIRVisionTextElement = line.elements.objectAtIndex(a);
57+
const bounds = element.frame;
58+
resultFeature.elements.push({
59+
text: element.text,
60+
bounds: bounds,
61+
});
62+
}
63+
};
64+
65+
if (feature instanceof FIRVisionTextBlock) {
66+
const textBlock = <FIRVisionTextBlock>feature;
67+
for (let j = 0, k = textBlock.lines.count; j < k; j++) {
68+
addLineToResult(textBlock.lines.objectAtIndex(j));
69+
}
70+
}
71+
72+
if (feature instanceof FIRVisionTextLine) {
73+
addLineToResult(feature);
74+
}
75+
76+
console.log(">>> resulting resultFeature: " + JSON.stringify(resultFeature));
77+
result.features.push(resultFeature);
78+
}
79+
return result;
80+
}
81+
7382
export function recognizeText(options: MLKitRecognizeTextOptions): Promise<MLKitRecognizeTextResult> {
7483
return new Promise((resolve, reject) => {
7584
try {
@@ -79,20 +88,8 @@ export function recognizeText(options: MLKitRecognizeTextOptions): Promise<MLKit
7988
textDetector.detectInImageCompletion(getImage(options), (features: NSArray<FIRVisionText>, error: NSError) => {
8089
if (error !== null) {
8190
reject(error.localizedDescription);
82-
8391
} else if (features !== null) {
84-
const result = <MLKitRecognizeTextResult>{
85-
features: []
86-
};
87-
88-
for (let i = 0, l = features.count; i < l; i++) {
89-
const feature: FIRVisionText = features.objectAtIndex(i);
90-
result.features.push({
91-
text: feature.text,
92-
// corners: <any>feature.cornerPoints
93-
});
94-
}
95-
resolve(result);
92+
resolve(getResult(features));
9693
}
9794
});
9895
} catch (ex) {

src/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nativescript-plugin-firebase",
3-
"version": "5.3.1",
3+
"version": "6.0.0",
44
"description": "Fire. Base. Firebase!",
55
"main": "firebase",
66
"typings": "index.d.ts",

0 commit comments

Comments
 (0)