cronapp-plugin-mlkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +25 -0
- package/plugin.xml +65 -0
- package/src/android/CronappMLKitPlugin.java +231 -0
- package/src/android/Utils.java +299 -0
- package/src/ios/CronappMLKitExtensions.swift +231 -0
- package/src/ios/CronappMLKitPlugin.swift +163 -0
- package/www/cronapp-mlkit.js +17 -0
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cronapp-plugin-mlkit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"cordova": {
|
|
6
|
+
"id": "cronapp-plugin-mlkit",
|
|
7
|
+
"platforms": [
|
|
8
|
+
"ios",
|
|
9
|
+
"android"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"cronapp",
|
|
14
|
+
"mlkit",
|
|
15
|
+
"ocr",
|
|
16
|
+
"ecosystem:cordova",
|
|
17
|
+
"cordova-ios",
|
|
18
|
+
"cordova-android"
|
|
19
|
+
],
|
|
20
|
+
"author": "Cronapp Team",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/plugin.xml
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<?xml version='1.0' encoding='utf-8'?>
|
|
2
|
+
<plugin id="cronapp-plugin-mlkit" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<name>CronappMLKitPlugin</name>
|
|
4
|
+
|
|
5
|
+
<js-module name="CronappMLKitPlugin" src="www/cronapp-mlkit.js">
|
|
6
|
+
<clobbers target="CronappMLKitPlugin" />
|
|
7
|
+
</js-module>
|
|
8
|
+
<platform name="ios">
|
|
9
|
+
<dependency id="cordova-plugin-add-swift-support" version="2.0.2"/>
|
|
10
|
+
|
|
11
|
+
<config-file target="config.xml" parent="/*">
|
|
12
|
+
<feature name="CronappMLKitPlugin">
|
|
13
|
+
<param name="ios-package" value="CronappMLKitPlugin" />
|
|
14
|
+
<param name="onload" value="true" />
|
|
15
|
+
</feature>
|
|
16
|
+
</config-file>
|
|
17
|
+
|
|
18
|
+
<source-file src="src/ios/CronappMLKitPlugin.swift" />
|
|
19
|
+
<source-file src="src/ios/CronappMLKitExtensions.swift" />
|
|
20
|
+
|
|
21
|
+
<podspec>
|
|
22
|
+
<config>
|
|
23
|
+
<source url="https://cdn.cocoapods.org/"/>
|
|
24
|
+
</config>
|
|
25
|
+
<pods use-frameworks="true">
|
|
26
|
+
<pod name="GoogleMLKit/TextRecognition"/>
|
|
27
|
+
<pod name="GoogleMLKit/BarcodeScanning"/>
|
|
28
|
+
<pod name="GoogleMLKit/ImageLabeling"/>
|
|
29
|
+
<pod name="GoogleMLKit/FaceDetection"/>
|
|
30
|
+
</pods>
|
|
31
|
+
</podspec>
|
|
32
|
+
</platform>
|
|
33
|
+
|
|
34
|
+
<platform name="android">
|
|
35
|
+
<dependency id="cordova-plugin-androidx" version="^2.0.0" />
|
|
36
|
+
<dependency id="cordova-plugin-androidx-adapter" version="^1.1.1" />
|
|
37
|
+
|
|
38
|
+
<config-file target="res/xml/config.xml" parent="/*">
|
|
39
|
+
<feature name="CronappMLKitPlugin">
|
|
40
|
+
<param name="android-package" value="io.cronapp.mlkit.CronappMLKitPlugin" />
|
|
41
|
+
<param name="onload" value="true" />
|
|
42
|
+
</feature>
|
|
43
|
+
</config-file>
|
|
44
|
+
|
|
45
|
+
<config-file target="AndroidManifest.xml" parent="/manifest/application">
|
|
46
|
+
<meta-data
|
|
47
|
+
android:name="com.google.mlkit.vision.DEPENDENCIES"
|
|
48
|
+
android:value="ocr" />
|
|
49
|
+
</config-file>
|
|
50
|
+
|
|
51
|
+
<source-file src="src/android/CronappMLKitPlugin.java" target-dir="io/cronapp/mlkit"/>
|
|
52
|
+
<source-file src="src/android/Utils.java" target-dir="io/cronapp/mlkit"/>
|
|
53
|
+
|
|
54
|
+
<preference name="MKLKIT_VERSION_TEXT_RECOGNITION" default="16.1.1"/>
|
|
55
|
+
<preference name="MKLKIT_VERSION_BARCODE" default="16.0.3"/>
|
|
56
|
+
<preference name="MKLKIT_VERSION_IMAGE_LABELLING" default="17.0.0"/>
|
|
57
|
+
<preference name="MKLKIT_VERSION_FACE" default="16.1.7"/>
|
|
58
|
+
|
|
59
|
+
<framework src="com.google.android.gms:play-services-mlkit-text-recognition:$MKLKIT_VERSION_TEXT_RECOGNITION"/>
|
|
60
|
+
<framework src="com.google.mlkit:barcode-scanning:$MKLKIT_VERSION_BARCODE"/>
|
|
61
|
+
<framework src="com.google.mlkit:image-labeling:$MKLKIT_VERSION_IMAGE_LABELLING"/>
|
|
62
|
+
<framework src="com.google.mlkit:face-detection:$MKLKIT_VERSION_FACE"/>
|
|
63
|
+
|
|
64
|
+
</platform>
|
|
65
|
+
</plugin>
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
package io.cronapp.mlkit;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.graphics.Bitmap;
|
|
6
|
+
import android.graphics.BitmapFactory;
|
|
7
|
+
import android.util.Base64;
|
|
8
|
+
|
|
9
|
+
import com.google.android.gms.tasks.OnFailureListener;
|
|
10
|
+
import com.google.android.gms.tasks.OnSuccessListener;
|
|
11
|
+
import com.google.mlkit.vision.barcode.Barcode;
|
|
12
|
+
import com.google.mlkit.vision.barcode.BarcodeScanner;
|
|
13
|
+
import com.google.mlkit.vision.barcode.BarcodeScanning;
|
|
14
|
+
import com.google.mlkit.vision.common.InputImage;
|
|
15
|
+
import com.google.mlkit.vision.face.Face;
|
|
16
|
+
import com.google.mlkit.vision.face.FaceDetection;
|
|
17
|
+
import com.google.mlkit.vision.face.FaceDetector;
|
|
18
|
+
import com.google.mlkit.vision.face.FaceDetectorOptions;
|
|
19
|
+
import com.google.mlkit.vision.label.ImageLabel;
|
|
20
|
+
import com.google.mlkit.vision.label.ImageLabeler;
|
|
21
|
+
import com.google.mlkit.vision.label.ImageLabeling;
|
|
22
|
+
import com.google.mlkit.vision.label.defaults.ImageLabelerOptions;
|
|
23
|
+
import com.google.mlkit.vision.text.Text;
|
|
24
|
+
import com.google.mlkit.vision.text.TextRecognition;
|
|
25
|
+
import com.google.mlkit.vision.text.TextRecognizer;
|
|
26
|
+
|
|
27
|
+
import org.apache.cordova.CallbackContext;
|
|
28
|
+
import org.apache.cordova.CordovaPlugin;
|
|
29
|
+
import org.json.JSONArray;
|
|
30
|
+
import org.json.JSONException;
|
|
31
|
+
import org.json.JSONObject;
|
|
32
|
+
|
|
33
|
+
import java.io.ByteArrayOutputStream;
|
|
34
|
+
import java.io.IOException;
|
|
35
|
+
import java.io.InputStream;
|
|
36
|
+
import java.util.List;
|
|
37
|
+
|
|
38
|
+
import androidx.annotation.NonNull;
|
|
39
|
+
|
|
40
|
+
public class CronappMLKitPlugin extends CordovaPlugin {
|
|
41
|
+
|
|
42
|
+
protected static Context applicationContext = null;
|
|
43
|
+
private static Activity cordovaActivity = null;
|
|
44
|
+
|
|
45
|
+
@Override
|
|
46
|
+
protected void pluginInitialize() {
|
|
47
|
+
super.pluginInitialize();
|
|
48
|
+
cordovaActivity = this.cordova.getActivity();
|
|
49
|
+
applicationContext = cordovaActivity.getApplicationContext();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@Override
|
|
53
|
+
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
54
|
+
if (action.equals("onDeviceTextRecognizer")) {
|
|
55
|
+
String message = args.getString(0);
|
|
56
|
+
this.onDeviceTextRecognizer(message, callbackContext);
|
|
57
|
+
return true;
|
|
58
|
+
} else if (action.equals("barcodeDetector")) {
|
|
59
|
+
String message = args.getString(0);
|
|
60
|
+
this.barcodeDetector(message, callbackContext);
|
|
61
|
+
return true;
|
|
62
|
+
} else if (action.equals("imageLabeler")) {
|
|
63
|
+
String message = args.getString(0);
|
|
64
|
+
this.imageLabeler(message, callbackContext);
|
|
65
|
+
return true;
|
|
66
|
+
} else if (action.equals("faceDetector")) {
|
|
67
|
+
String message = args.getString(0);
|
|
68
|
+
JSONObject options = args.getJSONObject(1);
|
|
69
|
+
this.faceDetector(message, options, callbackContext);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private void onDeviceTextRecognizer(String message, CallbackContext callbackContext) {
|
|
76
|
+
if (message != null && message.length() > 0) {
|
|
77
|
+
try {
|
|
78
|
+
InputImage image = getImage(message);
|
|
79
|
+
TextRecognizer recognizer = TextRecognition.getClient();
|
|
80
|
+
recognizer.process(image)
|
|
81
|
+
.addOnSuccessListener(new OnSuccessListener<Text>() {
|
|
82
|
+
@Override
|
|
83
|
+
public void onSuccess(Text firebaseVisionText) {
|
|
84
|
+
try {
|
|
85
|
+
JSONObject text = Utils.parseText(image, firebaseVisionText);
|
|
86
|
+
callbackContext.success(text);
|
|
87
|
+
} catch (Exception e) {
|
|
88
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
.addOnFailureListener(new OnFailureListener() {
|
|
93
|
+
@Override
|
|
94
|
+
public void onFailure(@NonNull Exception e) {
|
|
95
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
} catch (Exception e) {
|
|
99
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
callbackContext.error("Expected one non-empty string argument.");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private void barcodeDetector(String message, CallbackContext callbackContext) {
|
|
107
|
+
if (message != null && message.length() > 0) {
|
|
108
|
+
try {
|
|
109
|
+
InputImage image = getImage(message);
|
|
110
|
+
BarcodeScanner detector = BarcodeScanning.getClient();
|
|
111
|
+
detector.process(image)
|
|
112
|
+
.addOnSuccessListener(new OnSuccessListener<List<Barcode>>() {
|
|
113
|
+
@Override
|
|
114
|
+
public void onSuccess(List<Barcode> firebaseVisionBarcodes) {
|
|
115
|
+
try {
|
|
116
|
+
JSONArray barcodes = Utils.parseBarcodes(image, firebaseVisionBarcodes);
|
|
117
|
+
callbackContext.success(barcodes);
|
|
118
|
+
} catch (Exception e) {
|
|
119
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
.addOnFailureListener(new OnFailureListener() {
|
|
124
|
+
@Override
|
|
125
|
+
public void onFailure(@NonNull Exception e) {
|
|
126
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
} catch (Exception e) {
|
|
130
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
callbackContext.error("Expected one non-empty string argument.");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private void imageLabeler(String message, CallbackContext callbackContext) {
|
|
138
|
+
if (message != null && message.length() > 0) {
|
|
139
|
+
try {
|
|
140
|
+
InputImage image = getImage(message);
|
|
141
|
+
ImageLabeler detector = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS);
|
|
142
|
+
detector.process(image)
|
|
143
|
+
.addOnSuccessListener(new OnSuccessListener<List<ImageLabel>>() {
|
|
144
|
+
@Override
|
|
145
|
+
public void onSuccess(List<ImageLabel> imageLabels) {
|
|
146
|
+
try {
|
|
147
|
+
JSONArray imageLabels1 = Utils.parseImageLabels(imageLabels);
|
|
148
|
+
callbackContext.success(imageLabels1);
|
|
149
|
+
} catch (Exception e) {
|
|
150
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
.addOnFailureListener(new OnFailureListener() {
|
|
155
|
+
@Override
|
|
156
|
+
public void onFailure(@NonNull Exception e) {
|
|
157
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
} catch (Exception e) {
|
|
161
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
callbackContext.error("Expected one non-empty string argument.");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private void faceDetector(String message, JSONObject options, CallbackContext callbackContext) {
|
|
169
|
+
if (message != null && message.length() > 0) {
|
|
170
|
+
try {
|
|
171
|
+
InputImage image = getImage(message);
|
|
172
|
+
FaceDetectorOptions faceDetectorOptions = new FaceDetectorOptions.Builder()
|
|
173
|
+
.setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
|
|
174
|
+
|
|
175
|
+
.build();
|
|
176
|
+
FaceDetector detector = FaceDetection.getClient(faceDetectorOptions);
|
|
177
|
+
detector.process(image)
|
|
178
|
+
.addOnSuccessListener(new OnSuccessListener<List<Face>>() {
|
|
179
|
+
@Override
|
|
180
|
+
public void onSuccess(List<Face> faces) {
|
|
181
|
+
try {
|
|
182
|
+
JSONArray imageLabels1 = Utils.parseFaces(faces);
|
|
183
|
+
callbackContext.success(imageLabels1);
|
|
184
|
+
} catch (Exception e) {
|
|
185
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
})
|
|
189
|
+
.addOnFailureListener(new OnFailureListener() {
|
|
190
|
+
@Override
|
|
191
|
+
public void onFailure(@NonNull Exception e) {
|
|
192
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
} catch (Exception e) {
|
|
196
|
+
callbackContext.error(e.getLocalizedMessage());
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
callbackContext.error("Expected one non-empty string argument.");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private byte[] toBytes(InputStream stream) throws IOException {
|
|
204
|
+
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
205
|
+
|
|
206
|
+
int nRead;
|
|
207
|
+
byte[] data = new byte[16384];
|
|
208
|
+
|
|
209
|
+
while ((nRead = stream.read(data, 0, data.length)) != -1) {
|
|
210
|
+
buffer.write(data, 0, nRead);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return buffer.toByteArray();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private InputImage getImage(String message) throws IOException {
|
|
217
|
+
if (message.contains("data:")) {
|
|
218
|
+
message = message
|
|
219
|
+
.replace("data:image/png;base64,", "")
|
|
220
|
+
.replace("data:image/jpeg;base64,", "");
|
|
221
|
+
byte[] decodedString = Base64.decode(message, Base64.DEFAULT);
|
|
222
|
+
Bitmap bitMap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
|
|
223
|
+
InputImage image = InputImage.fromBitmap(bitMap, 0);
|
|
224
|
+
return image;
|
|
225
|
+
} else {
|
|
226
|
+
Uri uri = Uri.parse("/sdcard/Download/face.jpg");
|
|
227
|
+
InputImage image = InputImage.fromFilePath(applicationContext, uri);
|
|
228
|
+
return image;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
package io.cronapp.mlkit;
|
|
2
|
+
|
|
3
|
+
import android.graphics.Point;
|
|
4
|
+
import android.graphics.Rect;
|
|
5
|
+
import android.text.TextUtils;
|
|
6
|
+
|
|
7
|
+
import com.google.mlkit.vision.barcode.Barcode;
|
|
8
|
+
import com.google.mlkit.vision.common.InputImage;
|
|
9
|
+
import com.google.mlkit.vision.face.Face;
|
|
10
|
+
import com.google.mlkit.vision.label.ImageLabel;
|
|
11
|
+
import com.google.mlkit.vision.text.Text;
|
|
12
|
+
|
|
13
|
+
import org.json.JSONArray;
|
|
14
|
+
import org.json.JSONObject;
|
|
15
|
+
|
|
16
|
+
import java.util.List;
|
|
17
|
+
import java.util.Locale;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
public class Utils {
|
|
21
|
+
public static JSONObject parseText(InputImage image, Text text) throws Exception {
|
|
22
|
+
JSONArray blocks = new JSONArray();
|
|
23
|
+
for (Text.TextBlock textBlock : text.getTextBlocks()) {
|
|
24
|
+
JSONArray lines = new JSONArray();
|
|
25
|
+
for (Text.Line line : textBlock.getLines()) {
|
|
26
|
+
JSONArray elements = new JSONArray();
|
|
27
|
+
for (Text.Element element : line.getElements()) {
|
|
28
|
+
JSONObject elementObject = new JSONObject();
|
|
29
|
+
elementObject.put("cornerPoints", parsePoints(element.getCornerPoints()));
|
|
30
|
+
elementObject.put("text", element.getText());
|
|
31
|
+
elementObject.put("frame", parseBoundingBox(element.getBoundingBox()));
|
|
32
|
+
elementObject.put("recognizedLanguages", element.getRecognizedLanguage());
|
|
33
|
+
elements.put(elementObject);
|
|
34
|
+
}
|
|
35
|
+
JSONObject lineObject = new JSONObject();
|
|
36
|
+
lineObject.put("cornerPoints", parsePoints(line.getCornerPoints()));
|
|
37
|
+
lineObject.put("text", line.getText());
|
|
38
|
+
lineObject.put("frame", parseBoundingBox(line.getBoundingBox()));
|
|
39
|
+
lineObject.put("recognizedLanguages", line.getRecognizedLanguage());
|
|
40
|
+
lineObject.put("elements", elements);
|
|
41
|
+
lines.put(lineObject);
|
|
42
|
+
}
|
|
43
|
+
JSONObject block = new JSONObject();
|
|
44
|
+
block.put("cornerPoints", parsePoints(textBlock.getCornerPoints()));
|
|
45
|
+
block.put("text", textBlock.getText());
|
|
46
|
+
block.put("frame", parseBoundingBox(textBlock.getBoundingBox()));
|
|
47
|
+
block.put("recognizedLanguages", textBlock.getRecognizedLanguage());
|
|
48
|
+
block.put("lines", lines);
|
|
49
|
+
blocks.put(block);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
JSONObject result = new JSONObject();
|
|
53
|
+
result.put("text", text.getText());
|
|
54
|
+
result.put("blocks", blocks);
|
|
55
|
+
result.put("imageWidth", image.getWidth());
|
|
56
|
+
result.put("imageHeight", image.getHeight());
|
|
57
|
+
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public static JSONArray parseBarcodes(InputImage image, List<Barcode> barcodes) throws Exception {
|
|
62
|
+
JSONArray array = new JSONArray();
|
|
63
|
+
for (Barcode barcode : barcodes) {
|
|
64
|
+
|
|
65
|
+
JSONObject barcodeMap = new JSONObject();
|
|
66
|
+
barcodeMap.put("valueType", barcode.getValueType());
|
|
67
|
+
barcodeMap.put("format", barcode.getFormat());
|
|
68
|
+
barcodeMap.put("rawValue", barcode.getRawValue());
|
|
69
|
+
barcodeMap.put("displayValue", barcode.getDisplayValue());
|
|
70
|
+
barcodeMap.put("cornerPoints", parsePoints(barcode.getCornerPoints()));
|
|
71
|
+
barcodeMap.put("boundingBox", barcode.getBoundingBox());
|
|
72
|
+
barcodeMap.put("imageWidth", image.getWidth());
|
|
73
|
+
barcodeMap.put("imageHeight", image.getHeight());
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if (barcode.getEmail() != null) {
|
|
77
|
+
JSONObject email = new JSONObject();
|
|
78
|
+
email.put("address", barcode.getEmail().getAddress());
|
|
79
|
+
email.put("body", barcode.getEmail().getBody());
|
|
80
|
+
email.put("subject", barcode.getEmail().getSubject());
|
|
81
|
+
email.put("type", barcode.getEmail().getType());
|
|
82
|
+
barcodeMap.put("email", email);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (barcode.getPhone() != null) {
|
|
86
|
+
JSONObject phone = new JSONObject();
|
|
87
|
+
phone.put("number", barcode.getPhone().getNumber());
|
|
88
|
+
phone.put("type", barcode.getPhone().getType());
|
|
89
|
+
barcodeMap.put("phone", phone);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (barcode.getSms() != null) {
|
|
93
|
+
JSONObject sms = new JSONObject();
|
|
94
|
+
sms.put("phoneNumber", barcode.getSms().getPhoneNumber());
|
|
95
|
+
sms.put("message", barcode.getSms().getMessage());
|
|
96
|
+
barcodeMap.put("sms", sms);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (barcode.getUrl() != null) {
|
|
100
|
+
JSONObject url = new JSONObject();
|
|
101
|
+
url.put("title", barcode.getUrl().getTitle());
|
|
102
|
+
url.put("url", barcode.getUrl().getUrl());
|
|
103
|
+
barcodeMap.put("url", url);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (barcode.getWifi() != null) {
|
|
107
|
+
JSONObject wifi = new JSONObject();
|
|
108
|
+
wifi.put("ssid", barcode.getWifi().getSsid());
|
|
109
|
+
wifi.put("password", barcode.getWifi().getPassword());
|
|
110
|
+
wifi.put("type", barcode.getWifi().getEncryptionType());
|
|
111
|
+
barcodeMap.put("wifi", wifi);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (barcode.getGeoPoint() != null) {
|
|
115
|
+
JSONObject geoPoint = new JSONObject();
|
|
116
|
+
geoPoint.put("latitude", barcode.getGeoPoint().getLat());
|
|
117
|
+
geoPoint.put("longitude", barcode.getGeoPoint().getLng());
|
|
118
|
+
barcodeMap.put("geoPoint", geoPoint);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (barcode.getCalendarEvent() != null) {
|
|
122
|
+
JSONObject calendarEvent = new JSONObject();
|
|
123
|
+
calendarEvent.put("eventDescription", barcode.getCalendarEvent().getDescription());
|
|
124
|
+
calendarEvent.put("location", barcode.getCalendarEvent().getLocation());
|
|
125
|
+
calendarEvent.put("organizer", barcode.getCalendarEvent().getOrganizer());
|
|
126
|
+
calendarEvent.put("status", barcode.getCalendarEvent().getStatus());
|
|
127
|
+
calendarEvent.put("summary", barcode.getCalendarEvent().getSummary());
|
|
128
|
+
calendarEvent.put("start", toISOString(barcode.getCalendarEvent().getStart()));
|
|
129
|
+
calendarEvent.put("end", toISOString(barcode.getCalendarEvent().getEnd()));
|
|
130
|
+
barcodeMap.put("calendarEvent", calendarEvent);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (barcode.getContactInfo() != null) {
|
|
134
|
+
JSONObject contactInfo = new JSONObject();
|
|
135
|
+
contactInfo.put("title", barcode.getContactInfo().getTitle());
|
|
136
|
+
contactInfo.put("name", barcode.getContactInfo().getName().getFormattedName());
|
|
137
|
+
contactInfo.put("addresses", parseAddresses(barcode.getContactInfo().getAddresses()));
|
|
138
|
+
contactInfo.put("phones", parsePhones(barcode.getContactInfo().getPhones()));
|
|
139
|
+
contactInfo.put("emails", parseEmails(barcode.getContactInfo().getEmails()));
|
|
140
|
+
contactInfo.put("organization", barcode.getContactInfo().getOrganization());
|
|
141
|
+
contactInfo.put("urls", TextUtils.join(",", barcode.getContactInfo().getUrls()));
|
|
142
|
+
barcodeMap.put("contactInfo", contactInfo);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (barcode.getDriverLicense() != null) {
|
|
146
|
+
JSONObject driverLicense = new JSONObject();
|
|
147
|
+
driverLicense.put("firstName", barcode.getDriverLicense().getFirstName());
|
|
148
|
+
driverLicense.put("middleName", barcode.getDriverLicense().getMiddleName());
|
|
149
|
+
driverLicense.put("lastName", barcode.getDriverLicense().getLastName());
|
|
150
|
+
driverLicense.put("gender", barcode.getDriverLicense().getGender());
|
|
151
|
+
driverLicense.put("addressCity", barcode.getDriverLicense().getAddressCity());
|
|
152
|
+
driverLicense.put("addressState", barcode.getDriverLicense().getAddressState());
|
|
153
|
+
driverLicense.put("addressStreet", barcode.getDriverLicense().getAddressStreet());
|
|
154
|
+
driverLicense.put("addressZip", barcode.getDriverLicense().getAddressZip());
|
|
155
|
+
driverLicense.put("birthDate", barcode.getDriverLicense().getBirthDate());
|
|
156
|
+
driverLicense.put("documentType", barcode.getDriverLicense().getDocumentType());
|
|
157
|
+
driverLicense.put("licenseNumber", barcode.getDriverLicense().getLicenseNumber());
|
|
158
|
+
driverLicense.put("expiryDate", barcode.getDriverLicense().getExpiryDate());
|
|
159
|
+
driverLicense.put("issuingDate", barcode.getDriverLicense().getIssueDate());
|
|
160
|
+
driverLicense.put("issuingCountry", barcode.getDriverLicense().getIssuingCountry());
|
|
161
|
+
barcodeMap.put("driverLicense", driverLicense);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
array.put(barcodeMap);
|
|
165
|
+
}
|
|
166
|
+
return array;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public static JSONArray parseImageLabels(List<ImageLabel> imageLabels) throws Exception {
|
|
170
|
+
JSONArray array = new JSONArray();
|
|
171
|
+
for (ImageLabel imageLabel : imageLabels) {
|
|
172
|
+
|
|
173
|
+
JSONObject imageLabelMap = new JSONObject();
|
|
174
|
+
imageLabelMap.put("text", imageLabel.getText());
|
|
175
|
+
imageLabelMap.put("confidence", imageLabel.getConfidence());
|
|
176
|
+
imageLabelMap.put("index", imageLabel.getIndex());
|
|
177
|
+
|
|
178
|
+
array.put(imageLabelMap);
|
|
179
|
+
}
|
|
180
|
+
return array;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public static JSONArray parseFaces(List<Face> faces) throws Exception {
|
|
184
|
+
JSONArray array = new JSONArray();
|
|
185
|
+
for (Face face : faces) {
|
|
186
|
+
|
|
187
|
+
array.put(FaceToJsonConverter.faceToJson(face));
|
|
188
|
+
}
|
|
189
|
+
return array;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private static JSONArray parsePhones(List<Barcode.Phone> phones) throws Exception {
|
|
193
|
+
JSONArray array = new JSONArray();
|
|
194
|
+
for (Barcode.Phone phone : phones) {
|
|
195
|
+
|
|
196
|
+
JSONObject phoneMap = new JSONObject();
|
|
197
|
+
phoneMap.put("number", phone.getNumber());
|
|
198
|
+
phoneMap.put("type", phone.getType());
|
|
199
|
+
|
|
200
|
+
array.put(phoneMap);
|
|
201
|
+
}
|
|
202
|
+
return array;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private static JSONArray parseAddresses(List<Barcode.Address> addresses) throws Exception {
|
|
206
|
+
JSONArray array = new JSONArray();
|
|
207
|
+
for (Barcode.Address address : addresses) {
|
|
208
|
+
|
|
209
|
+
JSONObject addressMap = new JSONObject();
|
|
210
|
+
addressMap.put("addressLine", TextUtils.join(",", address.getAddressLines()));
|
|
211
|
+
addressMap.put("type", address.getType());
|
|
212
|
+
|
|
213
|
+
array.put(addressMap);
|
|
214
|
+
}
|
|
215
|
+
return array;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private static JSONArray parseEmails(List<Barcode.Email> emails) throws Exception {
|
|
219
|
+
JSONArray array = new JSONArray();
|
|
220
|
+
for (Barcode.Email email : emails) {
|
|
221
|
+
|
|
222
|
+
JSONObject emailMap = new JSONObject();
|
|
223
|
+
emailMap.put("address", email.getAddress());
|
|
224
|
+
emailMap.put("body", email.getBody());
|
|
225
|
+
emailMap.put("subject", email.getSubject());
|
|
226
|
+
emailMap.put("type", email.getType());
|
|
227
|
+
|
|
228
|
+
array.put(emailMap);
|
|
229
|
+
}
|
|
230
|
+
return array;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private static JSONArray parsePoints(Point[] points) throws Exception {
|
|
234
|
+
JSONArray array = new JSONArray();
|
|
235
|
+
for (Point point : points) {
|
|
236
|
+
|
|
237
|
+
JSONObject pointMap = new JSONObject();
|
|
238
|
+
pointMap.put("x", point.x);
|
|
239
|
+
pointMap.put("y", point.y);
|
|
240
|
+
array.put(pointMap);
|
|
241
|
+
}
|
|
242
|
+
return array;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private static JSONObject parseBoundingBox(Rect rect) throws Exception {
|
|
246
|
+
JSONObject rectMap = new JSONObject();
|
|
247
|
+
rectMap.put("x", rect.left);
|
|
248
|
+
rectMap.put("y", rect.top);
|
|
249
|
+
rectMap.put("width", rect.width());
|
|
250
|
+
rectMap.put("height", rect.height());
|
|
251
|
+
|
|
252
|
+
return rectMap;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private static String toISOString(Barcode.CalendarDateTime date) {
|
|
256
|
+
return String.format(Locale.getDefault(), "%d-%02d-%02dT%02d:%02d:%02d",
|
|
257
|
+
date.getYear(), date.getMonth(), date.getDay(),
|
|
258
|
+
date.getHours(), date.getMinutes(), date.getSeconds());
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
public static JSONObject parseFaces(Face face) {
|
|
262
|
+
|
|
263
|
+
JSONObject faceData = new JSONObject();
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
faceData.put("faceId", face.getTrackingId());
|
|
267
|
+
JSONObject boundingBox = new JSONObject();
|
|
268
|
+
boundingBox.put("left", face.getBoundingBox().left);
|
|
269
|
+
boundingBox.put("top", face.getBoundingBox().top);
|
|
270
|
+
boundingBox.put("right", face.getBoundingBox().right);
|
|
271
|
+
boundingBox.put("bottom", face.getBoundingBox().bottom);
|
|
272
|
+
faceData.put("boundingBox", boundingBox);
|
|
273
|
+
faceData.put("headEulerAngleX", face.getHeadEulerAngleX());
|
|
274
|
+
faceData.put("headEulerAngleY", face.getHeadEulerAngleY());
|
|
275
|
+
faceData.put("headEulerAngleZ", face.getHeadEulerAngleZ());
|
|
276
|
+
|
|
277
|
+
faceData.put("smilingProbability", face.getSmilingProbability());
|
|
278
|
+
|
|
279
|
+
faceData.put("rightEyeOpenProbability", face.getRightEyeOpenProbability());
|
|
280
|
+
|
|
281
|
+
faceData.put("leftEyeOpenProbability", face.getLeftEyeOpenProbability());
|
|
282
|
+
|
|
283
|
+
JSONArray landmarksArray = new JSONArray();
|
|
284
|
+
for (FaceLandmark landmark : face.getAllLandmarks()) {
|
|
285
|
+
JSONObject landmarkData = new JSONObject();
|
|
286
|
+
landmarkData.put("type", landmark.getLandmarkType());
|
|
287
|
+
landmarkData.put("x", landmark.getPosition().x);
|
|
288
|
+
landmarkData.put("y", landmark.getPosition().y);
|
|
289
|
+
landmarksArray.put(landmarkData);
|
|
290
|
+
}
|
|
291
|
+
faceData.put("landmarks", landmarksArray);
|
|
292
|
+
} catch (Exception e) {
|
|
293
|
+
e.printStackTrace();
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return faceData;
|
|
297
|
+
|
|
298
|
+
}
|
|
299
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import MLKitTextRecognition
|
|
2
|
+
import MLKitBarcodeScanning
|
|
3
|
+
import MLKitImageLabeling
|
|
4
|
+
import MLKitFaceDetection
|
|
5
|
+
import UIKit
|
|
6
|
+
|
|
7
|
+
extension Text {
|
|
8
|
+
func toJSON(with image: UIImage) -> [AnyHashable: Any] {
|
|
9
|
+
let blocksParsed = blocks.compactMap { (block) -> Any? in
|
|
10
|
+
let lines = block.lines.compactMap { (line) -> Any? in
|
|
11
|
+
let elements = line.elements.compactMap { (element) -> Any? in
|
|
12
|
+
return [
|
|
13
|
+
"cornerPoints": element.cornerPoints.toJSON() as Any,
|
|
14
|
+
"text": element.text,
|
|
15
|
+
"frame": element.frame.toJSON() as Any
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
return [
|
|
19
|
+
"cornerPoints": line.cornerPoints.toJSON() as Any,
|
|
20
|
+
"text": line.text,
|
|
21
|
+
"frame": line.frame.toJSON() as Any,
|
|
22
|
+
"recognizedLanguages": line.recognizedLanguages.compactMap({$0.languageCode}),
|
|
23
|
+
"elements": elements
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
return [
|
|
27
|
+
"cornerPoints": block.cornerPoints.toJSON() as Any,
|
|
28
|
+
"text": block.text,
|
|
29
|
+
"frame": block.frame.toJSON() as Any,
|
|
30
|
+
"recognizedLanguages": block.recognizedLanguages.compactMap({$0.languageCode}),
|
|
31
|
+
"lines": lines
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return [
|
|
36
|
+
"text": text,
|
|
37
|
+
"blocks": blocksParsed,
|
|
38
|
+
"imageWidth": image.size.width,
|
|
39
|
+
"imageHeight": image.size.height
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
extension Face {
|
|
45
|
+
func toJSON(with image: UIImage) -> [AnyHashable: Any] {
|
|
46
|
+
var response: [AnyHashable: Any] = [:]
|
|
47
|
+
|
|
48
|
+
response["faceId"] = trackingID
|
|
49
|
+
|
|
50
|
+
let boundingBox = [
|
|
51
|
+
"x": frame.origin.x,
|
|
52
|
+
"y": frame.origin.y,
|
|
53
|
+
"width": frame.size.width,
|
|
54
|
+
"height": frame.size.height
|
|
55
|
+
]
|
|
56
|
+
response["boundingBox"] = boundingBox
|
|
57
|
+
|
|
58
|
+
response["headEulerAngleX"] = headEulerAngleX
|
|
59
|
+
response["headEulerAngleY"] = headEulerAngleY
|
|
60
|
+
response["headEulerAngleZ"] = headEulerAngleZ
|
|
61
|
+
|
|
62
|
+
response["smilingProbability"] = smilingProbability ?? -1
|
|
63
|
+
response["leftEyeOpenProbability"] = leftEyeOpenProbability ?? -1
|
|
64
|
+
response["rightEyeOpenProbability"] = rightEyeOpenProbability ?? -1
|
|
65
|
+
|
|
66
|
+
var landmarksArray: [[AnyHashable: Any]] = []
|
|
67
|
+
for landmark in landmarks {
|
|
68
|
+
var landmarkData: [AnyHashable: Any] = [:]
|
|
69
|
+
landmarkData["type"] = landmark.type.rawValue
|
|
70
|
+
landmarkData["x"] = landmark.position.x
|
|
71
|
+
landmarkData["y"] = landmark.position.y
|
|
72
|
+
|
|
73
|
+
landmarksArray.append(landmarkData)
|
|
74
|
+
}
|
|
75
|
+
response["landmarks"] = landmarksArray
|
|
76
|
+
|
|
77
|
+
return response
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
extension Barcode {
|
|
81
|
+
func toJSON(with image: UIImage) -> [AnyHashable: Any] {
|
|
82
|
+
var response = [
|
|
83
|
+
"valueType": valueType.rawValue,
|
|
84
|
+
"format": format.rawValue,
|
|
85
|
+
"rawValue" : rawValue as Any,
|
|
86
|
+
"displayValue" : displayValue as Any,
|
|
87
|
+
"cornerPoints" : cornerPoints?.toJSON() as Any,
|
|
88
|
+
"imageWidth": image.size.width,
|
|
89
|
+
"imageHeight": image.size.height
|
|
90
|
+
]
|
|
91
|
+
if let email = email {
|
|
92
|
+
response["email"] = [
|
|
93
|
+
"address" : email.address as Any,
|
|
94
|
+
"body" : email.body as Any,
|
|
95
|
+
"subject" : email.subject as Any,
|
|
96
|
+
"type" : email.type.rawValue as Any
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
if let phone = phone {
|
|
100
|
+
response["phone"] = [
|
|
101
|
+
"number" : phone.number as Any,
|
|
102
|
+
"type" : phone.type.rawValue as Any
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
if let sms = sms {
|
|
106
|
+
response["sms"] = [
|
|
107
|
+
"phoneNumber": sms.phoneNumber as Any,
|
|
108
|
+
"message": sms.message as Any
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
if let url = url {
|
|
112
|
+
response["url"] = [
|
|
113
|
+
"title": url.title as Any,
|
|
114
|
+
"url": url.url as Any
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
if let wifi = wifi {
|
|
118
|
+
response["wifi"] = [
|
|
119
|
+
"ssid" : wifi.ssid as Any,
|
|
120
|
+
"password" : wifi.password as Any,
|
|
121
|
+
"type" : wifi.type.rawValue as Any
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
if let geoPoint = geoPoint {
|
|
125
|
+
response["geoPoint"] = [
|
|
126
|
+
"latitude" : geoPoint.latitude as Any,
|
|
127
|
+
"longitude" : geoPoint.longitude as Any
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
if let calendarEvent = calendarEvent {
|
|
131
|
+
response["calendarEvent"] = [
|
|
132
|
+
"eventDescription": calendarEvent.eventDescription as Any,
|
|
133
|
+
"location": calendarEvent.location as Any,
|
|
134
|
+
"organizer": calendarEvent.organizer as Any,
|
|
135
|
+
"status": calendarEvent.status as Any,
|
|
136
|
+
"summary": calendarEvent.summary as Any,
|
|
137
|
+
"start": calendarEvent.start?.toISOString() as Any,
|
|
138
|
+
"end": calendarEvent.end?.toISOString() as Any
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if let contactInfo = contactInfo {
|
|
143
|
+
response["contactInfo"] = [
|
|
144
|
+
"title": contactInfo.jobTitle as Any,
|
|
145
|
+
"name": contactInfo.name?.formattedName as Any,
|
|
146
|
+
"addresses": contactInfo.addresses?.compactMap({ (address) -> [String: Any]? in
|
|
147
|
+
return [
|
|
148
|
+
"addressLine" : address.addressLines?.joined(separator: ",") as Any,
|
|
149
|
+
"type" : address.type.rawValue
|
|
150
|
+
]
|
|
151
|
+
}) as Any,
|
|
152
|
+
"phones": contactInfo.phones?.compactMap({ (phone) -> [String: Any]? in
|
|
153
|
+
return [
|
|
154
|
+
"number": phone.number as Any,
|
|
155
|
+
"type": phone.type.rawValue
|
|
156
|
+
]
|
|
157
|
+
}) as Any,
|
|
158
|
+
"emails": contactInfo.emails?.compactMap({ (email) -> [String: Any]? in
|
|
159
|
+
return [
|
|
160
|
+
"address": email.address as Any,
|
|
161
|
+
"body": email.body as Any,
|
|
162
|
+
"type": email.type.rawValue
|
|
163
|
+
]
|
|
164
|
+
}) as Any,
|
|
165
|
+
"organization": contactInfo.organization as Any,
|
|
166
|
+
"urls": contactInfo.urls?.joined(separator: ",") as Any
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
if let driverLicense = driverLicense {
|
|
172
|
+
response["driverLicense"] = [
|
|
173
|
+
"firstName": driverLicense.firstName as Any,
|
|
174
|
+
"middleName": driverLicense.middleName as Any,
|
|
175
|
+
"lastName": driverLicense.lastName as Any,
|
|
176
|
+
"gender": driverLicense.gender as Any,
|
|
177
|
+
"addressCity": driverLicense.addressCity as Any,
|
|
178
|
+
"addressState": driverLicense.addressState as Any,
|
|
179
|
+
"addressStreet": driverLicense.addressStreet as Any,
|
|
180
|
+
"addressZip": driverLicense.addressZip as Any,
|
|
181
|
+
"birthDate": driverLicense.birthDate as Any,
|
|
182
|
+
"documentType": driverLicense.documentType as Any,
|
|
183
|
+
"licenseNumber": driverLicense.licenseNumber as Any,
|
|
184
|
+
"expiryDate": driverLicense.expiryDate as Any,
|
|
185
|
+
"issuingDate": driverLicense.issuingDate as Any,
|
|
186
|
+
"issuingCountry": driverLicense.issuingCountry as Any
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
return response
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
extension ImageLabel {
|
|
194
|
+
func toJSON() -> [String: Any] {
|
|
195
|
+
return [
|
|
196
|
+
"text": text,
|
|
197
|
+
"index": index,
|
|
198
|
+
"confidence": confidence
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
extension Date {
|
|
204
|
+
func toISOString() -> String {
|
|
205
|
+
let formatter = DateFormatter()
|
|
206
|
+
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
|
|
207
|
+
return formatter.string(from: self)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
extension CGRect {
|
|
212
|
+
func toJSON() -> [AnyHashable: Any] {
|
|
213
|
+
return [
|
|
214
|
+
"x" : origin.x,
|
|
215
|
+
"y" : origin.y,
|
|
216
|
+
"width": size.width,
|
|
217
|
+
"height": size.height
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
extension Array where Element: NSValue {
|
|
223
|
+
func toJSON() -> [[AnyHashable: Any]] {
|
|
224
|
+
return self.compactMap({
|
|
225
|
+
[
|
|
226
|
+
"x" : ($0 as! CGPoint).x,
|
|
227
|
+
"y" : ($0 as! CGPoint).y
|
|
228
|
+
]
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import MLKitTextRecognition
|
|
2
|
+
import MLKitBarcodeScanning
|
|
3
|
+
import MLKitImageLabeling
|
|
4
|
+
import MLKitFaceDetection
|
|
5
|
+
import MLKitVision
|
|
6
|
+
import UIKit
|
|
7
|
+
|
|
8
|
+
@objc(CronappMLKitPlugin)
|
|
9
|
+
class CronappMLKitPlugin: CDVPlugin {
|
|
10
|
+
|
|
11
|
+
@objc(onDeviceTextRecognizer:)
|
|
12
|
+
func onDeviceTextRecognizer(command: CDVInvokedUrlCommand) {
|
|
13
|
+
guard let imageURL = command.arguments.first as? String else {
|
|
14
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Image URL required")
|
|
15
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
getImage(imageURL: imageURL) { (image, error) in
|
|
19
|
+
if let error = error {
|
|
20
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
21
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
22
|
+
} else {
|
|
23
|
+
let textRecognizer = TextRecognizer.textRecognizer()
|
|
24
|
+
let visionImage = VisionImage(image: image!)
|
|
25
|
+
textRecognizer.process(visionImage) { (text, error) in
|
|
26
|
+
if let error = error {
|
|
27
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
28
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
29
|
+
} else {
|
|
30
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: text?.toJSON(with: image!))
|
|
31
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@objc(faceDetector:)
|
|
40
|
+
func faceDetector(command: CDVInvokedUrlCommand) {
|
|
41
|
+
guard let imageURL = command.arguments.first as? String else {
|
|
42
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Image URL required")
|
|
43
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
getImage(imageURL: imageURL) { (image, error) in
|
|
47
|
+
if let error = error {
|
|
48
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
49
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
50
|
+
} else {
|
|
51
|
+
let faceDetector = FaceDetector.faceDetector()
|
|
52
|
+
let visionImage = VisionImage(image: image!)
|
|
53
|
+
faceDetector.process(visionImage) { (faces, error) in
|
|
54
|
+
if let error = error {
|
|
55
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
56
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
57
|
+
} else {
|
|
58
|
+
let barcodesDict = faces?.compactMap({ $0.toJSON(with: image!) })
|
|
59
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: barcodesDict)
|
|
60
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@objc(barcodeDetector:)
|
|
68
|
+
func barcodeDetector(command: CDVInvokedUrlCommand) {
|
|
69
|
+
guard let imageURL = command.arguments.first as? String else {
|
|
70
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Image URL required")
|
|
71
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
getImage(imageURL: imageURL) { (image, error) in
|
|
75
|
+
if let error = error {
|
|
76
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
77
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
78
|
+
} else {
|
|
79
|
+
let barcodeDetector = BarcodeScanner.barcodeScanner()
|
|
80
|
+
let visionImage = VisionImage(image: image!)
|
|
81
|
+
barcodeDetector.process(visionImage) { (barcodes, error) in
|
|
82
|
+
if let error = error {
|
|
83
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
84
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
85
|
+
} else {
|
|
86
|
+
let barcodesDict = barcodes?.compactMap({ $0.toJSON(with: image!) })
|
|
87
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: barcodesDict)
|
|
88
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@objc(imageLabeler:)
|
|
96
|
+
func imageLabeler(command: CDVInvokedUrlCommand) {
|
|
97
|
+
guard let imageURL = command.arguments.first as? String else {
|
|
98
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Image URL required")
|
|
99
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
getImage(imageURL: imageURL) { (image, error) in
|
|
103
|
+
if let error = error {
|
|
104
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
105
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
106
|
+
} else {
|
|
107
|
+
let options = ImageLabelerOptions()
|
|
108
|
+
options.confidenceThreshold = 0.7
|
|
109
|
+
let imageLabeler = ImageLabeler.imageLabeler(options: options)
|
|
110
|
+
let visionImage = VisionImage(image: image!)
|
|
111
|
+
imageLabeler.process(visionImage) { (labels, error) in
|
|
112
|
+
if let error = error {
|
|
113
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: error.localizedDescription)
|
|
114
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
115
|
+
} else {
|
|
116
|
+
let labelsDict = labels?.compactMap({$0.toJSON()})
|
|
117
|
+
let pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: labelsDict)
|
|
118
|
+
self.commandDelegate.send(pluginResult, callbackId: command.callbackId)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private func getImage(imageURL: String, _ completion: @escaping (_ image: UIImage?, _ error: Error?) -> Void) {
|
|
126
|
+
if imageURL.contains("data:") {
|
|
127
|
+
guard let data = Data(base64Encoded: imageURL
|
|
128
|
+
.replacingOccurrences(of: "data:image/jpeg;base64,", with: "")
|
|
129
|
+
.replacingOccurrences(of: "data:image/png;base64,", with: "")),
|
|
130
|
+
let image = UIImage(data: data) else {
|
|
131
|
+
let error = NSError(domain: "cronapp-plugin-mlkit",
|
|
132
|
+
code: -1,
|
|
133
|
+
userInfo: [NSLocalizedDescriptionKey : "Base64ImageError"])
|
|
134
|
+
completion(nil, error)
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
completion(image, nil)
|
|
138
|
+
} else {
|
|
139
|
+
guard let url = URL(string: imageURL) else {
|
|
140
|
+
let error = NSError(domain: "cronapp-plugin-mlkit",
|
|
141
|
+
code: -1,
|
|
142
|
+
userInfo: [NSLocalizedDescriptionKey : "URLImageError"])
|
|
143
|
+
completion(nil, error)
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
URLSession.shared.dataTask(with: url) { (data, response, error) in
|
|
147
|
+
if let error = error {
|
|
148
|
+
completion(nil, error)
|
|
149
|
+
} else {
|
|
150
|
+
guard let data = data, let image = UIImage(data: data) else {
|
|
151
|
+
let error = NSError(domain: "cronapp-plugin-mlkit",
|
|
152
|
+
code: -1,
|
|
153
|
+
userInfo: [NSLocalizedDescriptionKey : "DownloadImageError"])
|
|
154
|
+
completion(nil, error)
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
completion(image, nil)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
.resume()
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
var exec = require('cordova/exec');
|
|
2
|
+
|
|
3
|
+
exports.onDeviceTextRecognizer = function (image, success, error) {
|
|
4
|
+
exec(success, error,'CronappMLKitPlugin', 'onDeviceTextRecognizer', [image])
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
exports.barcodeDetector = function (image, success, error) {
|
|
8
|
+
exec(success, error,'CronappMLKitPlugin', 'barcodeDetector', [image])
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exports.imageLabeler = function (image, success, error) {
|
|
12
|
+
exec(success, error,'CronappMLKitPlugin', 'imageLabeler', [image])
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
exports.faceDetector = function (image, options, success, error) {
|
|
16
|
+
exec(success, error,'CronappMLKitPlugin', 'faceDetector', [image, options])
|
|
17
|
+
}
|