@scr2em/capacitor-scanner 6.0.21 → 6.0.23
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/README.md +19 -10
- package/android/src/main/java/com/leadliaion/capacitorscanner/CapacitorScannerPlugin.java +91 -32
- package/dist/docs.json +33 -9
- package/dist/esm/definitions.d.ts +36 -3
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/CapacitorScannerPlugin/CapacitorScannerPlugin.swift +74 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ npx cap sync
|
|
|
26
26
|
* [`removeAllListeners()`](#removealllisteners)
|
|
27
27
|
* [`enableObjectDetection(...)`](#enableobjectdetection)
|
|
28
28
|
* [`disableObjectDetection()`](#disableobjectdetection)
|
|
29
|
-
* [`enableBarcodeDetection()`](#enablebarcodedetection)
|
|
29
|
+
* [`enableBarcodeDetection(...)`](#enablebarcodedetection)
|
|
30
30
|
* [`disableBarcodeDetection()`](#disablebarcodedetection)
|
|
31
31
|
* [`zoom(...)`](#zoom)
|
|
32
32
|
* [Type Aliases](#type-aliases)
|
|
@@ -183,12 +183,12 @@ removeAllListeners() => any
|
|
|
183
183
|
### enableObjectDetection(...)
|
|
184
184
|
|
|
185
185
|
```typescript
|
|
186
|
-
enableObjectDetection(
|
|
186
|
+
enableObjectDetection(options: ObjectDetectionOptions) => any
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
| Param
|
|
190
|
-
|
|
|
191
|
-
| **`
|
|
189
|
+
| Param | Type |
|
|
190
|
+
| ------------- | ------------------------------------------------------------------------- |
|
|
191
|
+
| **`options`** | <code><a href="#objectdetectionoptions">ObjectDetectionOptions</a></code> |
|
|
192
192
|
|
|
193
193
|
**Returns:** <code>any</code>
|
|
194
194
|
|
|
@@ -206,13 +206,17 @@ disableObjectDetection() => any
|
|
|
206
206
|
--------------------
|
|
207
207
|
|
|
208
208
|
|
|
209
|
-
### enableBarcodeDetection()
|
|
209
|
+
### enableBarcodeDetection(...)
|
|
210
210
|
|
|
211
211
|
```typescript
|
|
212
|
-
enableBarcodeDetection() => any
|
|
212
|
+
enableBarcodeDetection(options?: BarcodeDetectionOptions | undefined) => any
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
-
Enable barcode detection. This will start detecting barcodes
|
|
215
|
+
Enable barcode detection. This will start detecting barcodes.
|
|
216
|
+
|
|
217
|
+
| Param | Type | Description |
|
|
218
|
+
| ------------- | --------------------------------------------------------------------------- | ---------------------------------------------- |
|
|
219
|
+
| **`options`** | <code><a href="#barcodedetectionoptions">BarcodeDetectionOptions</a></code> | - Optional configuration for barcode detection |
|
|
216
220
|
|
|
217
221
|
**Returns:** <code>any</code>
|
|
218
222
|
|
|
@@ -254,7 +258,7 @@ Set the camera zoom level.
|
|
|
254
258
|
|
|
255
259
|
#### StartOptions
|
|
256
260
|
|
|
257
|
-
<code>{ /** * Barcode formats to detect when barcodeDetection is enabled. */ formats?: BarcodeFormat[]; /** * Camera direction to use. Defaults to 'BACK'. */ cameraDirection?: 'BACK' | 'FRONT'; /** * Enable barcode detection on start. Defaults to false. * When enabled, the camera will automatically detect barcodes and emit 'barcodeScanned' events. */ barcodeDetection?: boolean; /** * Enable object detection (business card) on start. Defaults to false. * When enabled, the camera will automatically detect business cards and emit 'rectangleDetected' events. */ objectDetection?: boolean; }</code>
|
|
261
|
+
<code>{ /** * Barcode formats to detect when barcodeDetection is enabled. */ formats?: BarcodeFormat[]; /** * Camera direction to use. Defaults to 'BACK'. */ cameraDirection?: 'BACK' | 'FRONT'; /** * Enable barcode detection on start. Defaults to false. * When enabled, the camera will automatically detect barcodes and emit 'barcodeScanned' events. */ barcodeDetection?: boolean; /** * Whether to show the highlight overlay for detected barcodes. Defaults to false. * Only applies when barcodeDetection is true. */ barcodeHighlight?: boolean; /** * Enable object detection (business card) on start. Defaults to false. * When enabled, the camera will automatically detect business cards and emit 'rectangleDetected' events. */ objectDetection?: boolean; /** * Whether to show the highlight overlay for detected business cards. Defaults to true. * Only applies when objectDetection is true. */ objectHighlight?: boolean; debounceTimeInMilli?: number; /** * Optional regex pattern to filter scanned barcodes. * If provided, only barcodes matching this pattern will be reported. */ regex?: string; /** * Optional regex flags (e.g., 'i' for case-insensitive, 'm' for multiline). */ regexFlags?: string; }</code>
|
|
258
262
|
|
|
259
263
|
|
|
260
264
|
#### CapturePhotoOptions
|
|
@@ -289,7 +293,12 @@ Set the camera zoom level.
|
|
|
289
293
|
|
|
290
294
|
#### ObjectDetectionOptions
|
|
291
295
|
|
|
292
|
-
<code>{ /** * Detection types to enable. Only 'businessCard' is supported. * For barcode detection, use enableBarcodeDetection() instead. */ types: ('businessCard')[], /** * Optional padding ratio to apply around detected rectangles when cropping. * Value must be between 0 and 1, where: * - 0 = no padding * - 1 = 100% padding (not recommended) * Default is 0.01 (1%) if not specified. */ paddingRatio?: number }</code>
|
|
296
|
+
<code>{ /** * Detection types to enable. Only 'businessCard' is supported. * For barcode detection, use enableBarcodeDetection() instead. */ types: ('businessCard')[], /** * Optional padding ratio to apply around detected rectangles when cropping. * Value must be between 0 and 1, where: * - 0 = no padding * - 1 = 100% padding (not recommended) * Default is 0.01 (1%) if not specified. */ paddingRatio?: number, /** * Whether to show the highlight overlay for detected business cards. * Defaults to true. */ showHighlight?: boolean }</code>
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
#### BarcodeDetectionOptions
|
|
300
|
+
|
|
301
|
+
<code>{ /** * Whether to show the highlight overlay for detected barcodes. * Defaults to false. */ showHighlight?: boolean; }</code>
|
|
293
302
|
|
|
294
303
|
|
|
295
304
|
#### ZoomOptions
|
|
@@ -98,6 +98,7 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
98
98
|
private final AtomicBoolean isScanning = new AtomicBoolean(false);
|
|
99
99
|
private FrameLayout containerView;
|
|
100
100
|
private DetectionOverlay detectionOverlay;
|
|
101
|
+
private java.util.regex.Pattern regexFilter;
|
|
101
102
|
|
|
102
103
|
private OrientationEventListener orientationEventListener;
|
|
103
104
|
private Preview preview;
|
|
@@ -108,6 +109,7 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
108
109
|
private int currentLensFacing = CameraSelector.LENS_FACING_BACK;
|
|
109
110
|
|
|
110
111
|
private final Set<String> enabledDetectionTypes = new HashSet<>();
|
|
112
|
+
private final Set<String> enabledHighlightTypes = new HashSet<>(); // Controls overlay display
|
|
111
113
|
private float paddingRatio = 0.01f; // Default padding ratio of 1%
|
|
112
114
|
// Add detection history for temporal smoothing
|
|
113
115
|
private java.util.List<DetectionResult> recentDetectionResults = new java.util.ArrayList<>();
|
|
@@ -186,6 +188,9 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
186
188
|
// Read detection options (defaults to false)
|
|
187
189
|
boolean enableBarcodeDetection = call.getBoolean("barcodeDetection", false);
|
|
188
190
|
boolean enableObjectDetection = call.getBoolean("objectDetection", false);
|
|
191
|
+
// Read highlight options (barcode defaults to false, businessCard defaults to true)
|
|
192
|
+
boolean enableBarcodeHighlight = call.getBoolean("barcodeHighlight", false);
|
|
193
|
+
boolean enableObjectHighlight = call.getBoolean("objectHighlight", true);
|
|
189
194
|
|
|
190
195
|
getActivity().runOnUiThread(() -> {
|
|
191
196
|
// Stop any existing session first
|
|
@@ -196,11 +201,17 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
196
201
|
// Enable barcode detection if requested
|
|
197
202
|
if (enableBarcodeDetection) {
|
|
198
203
|
enabledDetectionTypes.add("barcode");
|
|
204
|
+
if (enableBarcodeHighlight) {
|
|
205
|
+
enabledHighlightTypes.add("barcode");
|
|
206
|
+
}
|
|
199
207
|
}
|
|
200
208
|
|
|
201
209
|
// Enable object detection (businessCard) if requested
|
|
202
210
|
if (enableObjectDetection) {
|
|
203
211
|
enabledDetectionTypes.add("businessCard");
|
|
212
|
+
if (enableObjectHighlight) {
|
|
213
|
+
enabledHighlightTypes.add("businessCard");
|
|
214
|
+
}
|
|
204
215
|
}
|
|
205
216
|
|
|
206
217
|
try {
|
|
@@ -215,6 +226,27 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
215
226
|
// **FIX**: Ensure currentLensFacing is updated when starting the scan
|
|
216
227
|
currentLensFacing = lensFacing;
|
|
217
228
|
|
|
229
|
+
// Handle Regex Filter
|
|
230
|
+
String regexPattern = call.getString("regex");
|
|
231
|
+
if (regexPattern != null) {
|
|
232
|
+
String flags = call.getString("regexFlags", "");
|
|
233
|
+
int patternFlags = 0;
|
|
234
|
+
if (flags.contains("i")) {
|
|
235
|
+
patternFlags |= java.util.regex.Pattern.CASE_INSENSITIVE;
|
|
236
|
+
}
|
|
237
|
+
if (flags.contains("m")) {
|
|
238
|
+
patternFlags |= java.util.regex.Pattern.MULTILINE;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
regexFilter = java.util.regex.Pattern.compile(regexPattern, patternFlags);
|
|
242
|
+
} catch (Exception e) {
|
|
243
|
+
call.reject("Invalid Regex pattern");
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
} else {
|
|
247
|
+
regexFilter = null;
|
|
248
|
+
}
|
|
249
|
+
|
|
218
250
|
JSArray formatsArray = call.getArray("formats");
|
|
219
251
|
BarcodeScannerOptions.Builder optionsBuilder = new BarcodeScannerOptions.Builder();
|
|
220
252
|
|
|
@@ -413,8 +445,11 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
413
445
|
scanner.process(image)
|
|
414
446
|
.addOnSuccessListener(executor, barcodes -> {
|
|
415
447
|
processBarcodes(barcodes);
|
|
416
|
-
|
|
417
|
-
|
|
448
|
+
// Only display barcode overlay if highlight is enabled
|
|
449
|
+
if (enabledHighlightTypes.contains("barcode")) {
|
|
450
|
+
displayDetectedBarcodes(barcodes, imageProxy.getWidth(), imageProxy.getHeight(),
|
|
451
|
+
imageProxy.getImageInfo().getRotationDegrees());
|
|
452
|
+
}
|
|
418
453
|
})
|
|
419
454
|
.addOnFailureListener(executor, e -> {
|
|
420
455
|
echo("Failed to process image for barcode: " + e.getMessage());
|
|
@@ -525,7 +560,8 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
525
560
|
// This runs for both freshly detected rectangles and reused detection results
|
|
526
561
|
final DetectionResult finalResult = detectionResult;
|
|
527
562
|
getActivity().runOnUiThread(() -> {
|
|
528
|
-
if
|
|
563
|
+
// Only display rectangle overlay if highlight is enabled
|
|
564
|
+
if (enabledHighlightTypes.contains("businessCard")) {
|
|
529
565
|
// Show the rectangles
|
|
530
566
|
displayDetectedRectangles(finalResult,
|
|
531
567
|
imageProxy.getWidth(),
|
|
@@ -787,6 +823,15 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
787
823
|
}
|
|
788
824
|
}
|
|
789
825
|
echo("Processing barcode with rawValue: " + rawValue);
|
|
826
|
+
|
|
827
|
+
// Apply Regex Filter if present
|
|
828
|
+
if (regexFilter != null) {
|
|
829
|
+
if (rawValue == null || !regexFilter.matcher(rawValue).find()) {
|
|
830
|
+
echo("Barcode " + rawValue + " does not match regex filter, skipping");
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
790
835
|
int format = barcode.getFormat();
|
|
791
836
|
|
|
792
837
|
VoteStatus voteStatus = scannedCodesVotes.get(rawValue);
|
|
@@ -1065,34 +1110,36 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1065
1110
|
detectionOverlay = null;
|
|
1066
1111
|
}
|
|
1067
1112
|
|
|
1068
|
-
|
|
1113
|
+
scannedCodesVotes.clear();
|
|
1114
|
+
regexFilter = null;
|
|
1069
1115
|
isScanning.set(false);
|
|
1070
1116
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
if (orientationEventListener != null) {
|
|
1074
|
-
orientationEventListener.disable();
|
|
1075
|
-
orientationEventListener = null;
|
|
1076
|
-
}
|
|
1117
|
+
showWebViewBackground();
|
|
1077
1118
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
lastRectangleProcessingTime = 0;
|
|
1083
|
-
lastRectangleDetectionTime = 0;
|
|
1119
|
+
if (orientationEventListener != null) {
|
|
1120
|
+
orientationEventListener.disable();
|
|
1121
|
+
orientationEventListener = null;
|
|
1122
|
+
}
|
|
1084
1123
|
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1124
|
+
// Reset all detection state variables
|
|
1125
|
+
lastGoodRectangleTime = 0;
|
|
1126
|
+
lastGoodDetectionResult = null;
|
|
1127
|
+
lastRectangleNotificationTime = 0;
|
|
1128
|
+
lastRectangleProcessingTime = 0;
|
|
1129
|
+
lastRectangleDetectionTime = 0;
|
|
1130
|
+
|
|
1131
|
+
// Clear detection histories and caches
|
|
1132
|
+
enabledDetectionTypes.clear();
|
|
1133
|
+
enabledHighlightTypes.clear();
|
|
1134
|
+
recentDetectionResults.clear();
|
|
1135
|
+
detectionHistory.clear();
|
|
1136
|
+
lastGoodRects = Collections.emptyList();
|
|
1090
1137
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1138
|
+
// Clear overlay rectangles
|
|
1139
|
+
synchronized (overlayLock) {
|
|
1140
|
+
currentBarcodeRects.clear();
|
|
1141
|
+
currentRectangleRects.clear();
|
|
1142
|
+
}
|
|
1096
1143
|
|
|
1097
1144
|
echo("All detection state variables have been reset");
|
|
1098
1145
|
}
|
|
@@ -1122,6 +1169,9 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1122
1169
|
});
|
|
1123
1170
|
}
|
|
1124
1171
|
|
|
1172
|
+
// Read showHighlight option (defaults to true for businessCard)
|
|
1173
|
+
boolean showHighlight = call.getBoolean("showHighlight", true);
|
|
1174
|
+
|
|
1125
1175
|
// Only accept "businessCard" type - barcode detection is handled separately
|
|
1126
1176
|
List<String> addedTypes = new ArrayList<>();
|
|
1127
1177
|
try {
|
|
@@ -1129,6 +1179,9 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1129
1179
|
String type = types.getString(i);
|
|
1130
1180
|
if ("businessCard".equals(type)) {
|
|
1131
1181
|
enabledDetectionTypes.add(type);
|
|
1182
|
+
if (showHighlight) {
|
|
1183
|
+
enabledHighlightTypes.add(type);
|
|
1184
|
+
}
|
|
1132
1185
|
addedTypes.add(type);
|
|
1133
1186
|
}
|
|
1134
1187
|
}
|
|
@@ -1175,7 +1228,7 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1175
1228
|
// this should not happen
|
|
1176
1229
|
}
|
|
1177
1230
|
|
|
1178
|
-
if (
|
|
1231
|
+
if (enabledHighlightTypes.contains("businessCard")) {
|
|
1179
1232
|
getActivity().runOnUiThread(() -> {
|
|
1180
1233
|
setupDetectionOverlay();
|
|
1181
1234
|
});
|
|
@@ -1186,8 +1239,9 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1186
1239
|
|
|
1187
1240
|
@PluginMethod
|
|
1188
1241
|
public void disableObjectDetection(PluginCall call) {
|
|
1189
|
-
//
|
|
1242
|
+
// Remove businessCard from both detection and highlight types
|
|
1190
1243
|
enabledDetectionTypes.remove("businessCard");
|
|
1244
|
+
enabledHighlightTypes.remove("businessCard");
|
|
1191
1245
|
|
|
1192
1246
|
// Reset businessCard detection state
|
|
1193
1247
|
detectionHistory.clear();
|
|
@@ -1558,11 +1612,15 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1558
1612
|
@PluginMethod
|
|
1559
1613
|
public void enableBarcodeDetection(PluginCall call) {
|
|
1560
1614
|
echo("enableBarcodeDetection");
|
|
1561
|
-
|
|
1615
|
+
boolean showHighlight = call.getBoolean("showHighlight", false);
|
|
1562
1616
|
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1617
|
+
enabledDetectionTypes.add("barcode");
|
|
1618
|
+
if (showHighlight) {
|
|
1619
|
+
enabledHighlightTypes.add("barcode");
|
|
1620
|
+
getActivity().runOnUiThread(() -> {
|
|
1621
|
+
setupDetectionOverlay();
|
|
1622
|
+
});
|
|
1623
|
+
}
|
|
1566
1624
|
|
|
1567
1625
|
JSObject result = new JSObject();
|
|
1568
1626
|
result.put("enabled", true);
|
|
@@ -1573,6 +1631,7 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1573
1631
|
public void disableBarcodeDetection(PluginCall call) {
|
|
1574
1632
|
echo("disableBarcodeDetection");
|
|
1575
1633
|
enabledDetectionTypes.remove("barcode");
|
|
1634
|
+
enabledHighlightTypes.remove("barcode");
|
|
1576
1635
|
|
|
1577
1636
|
// Clear cached barcodes
|
|
1578
1637
|
scannedCodesVotes.clear();
|
package/dist/docs.json
CHANGED
|
@@ -171,10 +171,10 @@
|
|
|
171
171
|
},
|
|
172
172
|
{
|
|
173
173
|
"name": "enableObjectDetection",
|
|
174
|
-
"signature": "(
|
|
174
|
+
"signature": "(options: ObjectDetectionOptions) => any",
|
|
175
175
|
"parameters": [
|
|
176
176
|
{
|
|
177
|
-
"name": "
|
|
177
|
+
"name": "options",
|
|
178
178
|
"docs": "",
|
|
179
179
|
"type": "ObjectDetectionOptions"
|
|
180
180
|
}
|
|
@@ -199,12 +199,25 @@
|
|
|
199
199
|
},
|
|
200
200
|
{
|
|
201
201
|
"name": "enableBarcodeDetection",
|
|
202
|
-
"signature": "() => any",
|
|
203
|
-
"parameters": [
|
|
202
|
+
"signature": "(options?: BarcodeDetectionOptions | undefined) => any",
|
|
203
|
+
"parameters": [
|
|
204
|
+
{
|
|
205
|
+
"name": "options",
|
|
206
|
+
"docs": "- Optional configuration for barcode detection",
|
|
207
|
+
"type": "BarcodeDetectionOptions | undefined"
|
|
208
|
+
}
|
|
209
|
+
],
|
|
204
210
|
"returns": "any",
|
|
205
|
-
"tags": [
|
|
206
|
-
|
|
207
|
-
|
|
211
|
+
"tags": [
|
|
212
|
+
{
|
|
213
|
+
"name": "param",
|
|
214
|
+
"text": "options - Optional configuration for barcode detection"
|
|
215
|
+
}
|
|
216
|
+
],
|
|
217
|
+
"docs": "Enable barcode detection. This will start detecting barcodes.",
|
|
218
|
+
"complexTypes": [
|
|
219
|
+
"BarcodeDetectionOptions"
|
|
220
|
+
],
|
|
208
221
|
"slug": "enablebarcodedetection"
|
|
209
222
|
},
|
|
210
223
|
{
|
|
@@ -326,7 +339,7 @@
|
|
|
326
339
|
"docs": "",
|
|
327
340
|
"types": [
|
|
328
341
|
{
|
|
329
|
-
"text": "{\n /**\n * Barcode formats to detect when barcodeDetection is enabled.\n */\n formats?: BarcodeFormat[];\n /**\n * Camera direction to use. Defaults to 'BACK'.\n */\n cameraDirection?: 'BACK' | 'FRONT';\n /**\n * Enable barcode detection on start. Defaults to false.\n * When enabled, the camera will automatically detect barcodes and emit 'barcodeScanned' events.\n */\n barcodeDetection?: boolean;\n /**\n * Enable object detection (business card) on start. Defaults to false.\n * When enabled, the camera will automatically detect business cards and emit 'rectangleDetected' events.\n */\n objectDetection?: boolean;\n}",
|
|
342
|
+
"text": "{\n /**\n * Barcode formats to detect when barcodeDetection is enabled.\n */\n formats?: BarcodeFormat[];\n /**\n * Camera direction to use. Defaults to 'BACK'.\n */\n cameraDirection?: 'BACK' | 'FRONT';\n /**\n * Enable barcode detection on start. Defaults to false.\n * When enabled, the camera will automatically detect barcodes and emit 'barcodeScanned' events.\n */\n barcodeDetection?: boolean;\n /**\n * Whether to show the highlight overlay for detected barcodes. Defaults to false.\n * Only applies when barcodeDetection is true.\n */\n barcodeHighlight?: boolean;\n /**\n * Enable object detection (business card) on start. Defaults to false.\n * When enabled, the camera will automatically detect business cards and emit 'rectangleDetected' events.\n */\n objectDetection?: boolean;\n /**\n * Whether to show the highlight overlay for detected business cards. Defaults to true.\n * Only applies when objectDetection is true.\n */\n objectHighlight?: boolean;\n debounceTimeInMilli?: number;\n /**\n * Optional regex pattern to filter scanned barcodes.\n * If provided, only barcodes matching this pattern will be reported.\n */\n regex?: string;\n /**\n * Optional regex flags (e.g., 'i' for case-insensitive, 'm' for multiline).\n */\n regexFlags?: string;\n}",
|
|
330
343
|
"complexTypes": [
|
|
331
344
|
"BarcodeFormat"
|
|
332
345
|
]
|
|
@@ -405,7 +418,18 @@
|
|
|
405
418
|
"docs": "",
|
|
406
419
|
"types": [
|
|
407
420
|
{
|
|
408
|
-
"text": "{\n /**\n * Detection types to enable. Only 'businessCard' is supported.\n * For barcode detection, use enableBarcodeDetection() instead.\n */\n types: ('businessCard')[],\n /**\n * Optional padding ratio to apply around detected rectangles when cropping.\n * Value must be between 0 and 1, where:\n * - 0 = no padding\n * - 1 = 100% padding (not recommended)\n * Default is 0.01 (1%) if not specified.\n */\n paddingRatio?: number\n}",
|
|
421
|
+
"text": "{\n /**\n * Detection types to enable. Only 'businessCard' is supported.\n * For barcode detection, use enableBarcodeDetection() instead.\n */\n types: ('businessCard')[],\n /**\n * Optional padding ratio to apply around detected rectangles when cropping.\n * Value must be between 0 and 1, where:\n * - 0 = no padding\n * - 1 = 100% padding (not recommended)\n * Default is 0.01 (1%) if not specified.\n */\n paddingRatio?: number,\n /**\n * Whether to show the highlight overlay for detected business cards.\n * Defaults to true.\n */\n showHighlight?: boolean\n}",
|
|
422
|
+
"complexTypes": []
|
|
423
|
+
}
|
|
424
|
+
]
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
"name": "BarcodeDetectionOptions",
|
|
428
|
+
"slug": "barcodedetectionoptions",
|
|
429
|
+
"docs": "",
|
|
430
|
+
"types": [
|
|
431
|
+
{
|
|
432
|
+
"text": "{\n /**\n * Whether to show the highlight overlay for detected barcodes.\n * Defaults to false.\n */\n showHighlight?: boolean;\n}",
|
|
409
433
|
"complexTypes": []
|
|
410
434
|
}
|
|
411
435
|
]
|
|
@@ -17,15 +17,16 @@ export interface CapacitorScannerPlugin {
|
|
|
17
17
|
addListener(event: 'barcodeScanned', listenerFunc: (result: BarcodeScannedEvent) => void): Promise<void>;
|
|
18
18
|
addListener(event: 'rectangleDetected', listenerFunc: (result: RectangleDetectedEvent) => void): Promise<void>;
|
|
19
19
|
removeAllListeners(): Promise<void>;
|
|
20
|
-
enableObjectDetection(
|
|
20
|
+
enableObjectDetection(options: ObjectDetectionOptions): Promise<void>;
|
|
21
21
|
disableObjectDetection(): Promise<{
|
|
22
22
|
enabled: false;
|
|
23
23
|
types: [];
|
|
24
24
|
}>;
|
|
25
25
|
/**
|
|
26
|
-
* Enable barcode detection. This will start detecting barcodes
|
|
26
|
+
* Enable barcode detection. This will start detecting barcodes.
|
|
27
|
+
* @param options - Optional configuration for barcode detection
|
|
27
28
|
*/
|
|
28
|
-
enableBarcodeDetection(): Promise<{
|
|
29
|
+
enableBarcodeDetection(options?: BarcodeDetectionOptions): Promise<{
|
|
29
30
|
enabled: true;
|
|
30
31
|
}>;
|
|
31
32
|
/**
|
|
@@ -40,6 +41,13 @@ export interface CapacitorScannerPlugin {
|
|
|
40
41
|
*/
|
|
41
42
|
zoom(options: ZoomOptions): Promise<ZoomResult>;
|
|
42
43
|
}
|
|
44
|
+
export declare type BarcodeDetectionOptions = {
|
|
45
|
+
/**
|
|
46
|
+
* Whether to show the highlight overlay for detected barcodes.
|
|
47
|
+
* Defaults to false.
|
|
48
|
+
*/
|
|
49
|
+
showHighlight?: boolean;
|
|
50
|
+
};
|
|
43
51
|
export declare type ObjectDetectionOptions = {
|
|
44
52
|
/**
|
|
45
53
|
* Detection types to enable. Only 'businessCard' is supported.
|
|
@@ -54,6 +62,11 @@ export declare type ObjectDetectionOptions = {
|
|
|
54
62
|
* Default is 0.01 (1%) if not specified.
|
|
55
63
|
*/
|
|
56
64
|
paddingRatio?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Whether to show the highlight overlay for detected business cards.
|
|
67
|
+
* Defaults to true.
|
|
68
|
+
*/
|
|
69
|
+
showHighlight?: boolean;
|
|
57
70
|
};
|
|
58
71
|
export declare type StartOptions = {
|
|
59
72
|
/**
|
|
@@ -69,11 +82,31 @@ export declare type StartOptions = {
|
|
|
69
82
|
* When enabled, the camera will automatically detect barcodes and emit 'barcodeScanned' events.
|
|
70
83
|
*/
|
|
71
84
|
barcodeDetection?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Whether to show the highlight overlay for detected barcodes. Defaults to false.
|
|
87
|
+
* Only applies when barcodeDetection is true.
|
|
88
|
+
*/
|
|
89
|
+
barcodeHighlight?: boolean;
|
|
72
90
|
/**
|
|
73
91
|
* Enable object detection (business card) on start. Defaults to false.
|
|
74
92
|
* When enabled, the camera will automatically detect business cards and emit 'rectangleDetected' events.
|
|
75
93
|
*/
|
|
76
94
|
objectDetection?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Whether to show the highlight overlay for detected business cards. Defaults to true.
|
|
97
|
+
* Only applies when objectDetection is true.
|
|
98
|
+
*/
|
|
99
|
+
objectHighlight?: boolean;
|
|
100
|
+
debounceTimeInMilli?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Optional regex pattern to filter scanned barcodes.
|
|
103
|
+
* If provided, only barcodes matching this pattern will be reported.
|
|
104
|
+
*/
|
|
105
|
+
regex?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Optional regex flags (e.g., 'i' for case-insensitive, 'm' for multiline).
|
|
108
|
+
*/
|
|
109
|
+
regexFlags?: string;
|
|
77
110
|
};
|
|
78
111
|
export declare type BarcodeScannedEvent = {
|
|
79
112
|
scannedCode: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AA4JA,MAAM,CAAN,IAAY,aAYX;AAZD,WAAY,aAAa;IACvB,gCAAe,CAAA;IACf,mCAAkB,CAAA;IAClB,mCAAkB,CAAA;IAClB,qCAAoB,CAAA;IACpB,2CAA0B,CAAA;IAC1B,+BAAc,CAAA;IACd,iCAAgB,CAAA;IAChB,gCAAe,CAAA;IACf,mCAAkB,CAAA;IAClB,mCAAkB,CAAA;IAClB,+BAAc,CAAA;AAChB,CAAC,EAZW,aAAa,KAAb,aAAa,QAYxB","sourcesContent":["export interface CapacitorScannerPlugin {\n /**\n * Start the camera preview with optional barcode and object detection.\n * @param options - Configuration options for the camera and detection\n */\n start(options?: StartOptions): Promise<void>;\n\n /**\n * Stop the camera preview and all detection.\n */\n stop(): Promise<void>;\n\n openSettings(): Promise<void>;\n\n capturePhoto(options?: CapturePhotoOptions): Promise<CapturePhotoResult>;\n\n checkPermissions(): Promise<PermissionsResult>;\n\n requestPermissions(): Promise<PermissionsResult>;\n\n flipCamera(): Promise<void>;\n\n toggleFlash(): Promise<FlashResult>;\n\n addListener(event: 'barcodeScanned', listenerFunc: (result: BarcodeScannedEvent) => void): Promise<void>;\n\n addListener(event: 'rectangleDetected', listenerFunc: (result: RectangleDetectedEvent) => void): Promise<void>;\n\n removeAllListeners(): Promise<void>;\n\n enableObjectDetection(options: ObjectDetectionOptions): Promise<void>;\n\n disableObjectDetection(): Promise<{ enabled: false, types: [] }>;\n\n /**\n * Enable barcode detection. This will start detecting barcodes.\n * @param options - Optional configuration for barcode detection\n */\n enableBarcodeDetection(options?: BarcodeDetectionOptions): Promise<{ enabled: true }>;\n\n /**\n * Disable barcode detection. This will stop detecting barcodes and clear cached barcodes.\n */\n disableBarcodeDetection(): Promise<{ enabled: false }>;\n\n /**\n * Set the camera zoom level.\n * @param options - The zoom options containing the level (1, 2, or 3)\n */\n zoom(options: ZoomOptions): Promise<ZoomResult>;\n}\n\nexport type BarcodeDetectionOptions = {\n /**\n * Whether to show the highlight overlay for detected barcodes.\n * Defaults to false.\n */\n showHighlight?: boolean;\n}\n\nexport type ObjectDetectionOptions = {\n /**\n * Detection types to enable. Only 'businessCard' is supported.\n * For barcode detection, use enableBarcodeDetection() instead.\n */\n types: ('businessCard')[],\n /**\n * Optional padding ratio to apply around detected rectangles when cropping.\n * Value must be between 0 and 1, where:\n * - 0 = no padding\n * - 1 = 100% padding (not recommended)\n * Default is 0.01 (1%) if not specified.\n */\n paddingRatio?: number,\n /**\n * Whether to show the highlight overlay for detected business cards.\n * Defaults to true.\n */\n showHighlight?: boolean\n}\n\nexport type StartOptions = {\n /**\n * Barcode formats to detect when barcodeDetection is enabled.\n */\n formats?: BarcodeFormat[];\n /**\n * Camera direction to use. Defaults to 'BACK'.\n */\n cameraDirection?: 'BACK' | 'FRONT';\n /**\n * Enable barcode detection on start. Defaults to false.\n * When enabled, the camera will automatically detect barcodes and emit 'barcodeScanned' events.\n */\n barcodeDetection?: boolean;\n /**\n * Whether to show the highlight overlay for detected barcodes. Defaults to false.\n * Only applies when barcodeDetection is true.\n */\n barcodeHighlight?: boolean;\n /**\n * Enable object detection (business card) on start. Defaults to false.\n * When enabled, the camera will automatically detect business cards and emit 'rectangleDetected' events.\n */\n objectDetection?: boolean;\n /**\n * Whether to show the highlight overlay for detected business cards. Defaults to true.\n * Only applies when objectDetection is true.\n */\n objectHighlight?: boolean;\n debounceTimeInMilli?: number;\n /**\n * Optional regex pattern to filter scanned barcodes.\n * If provided, only barcodes matching this pattern will be reported.\n */\n regex?: string;\n /**\n * Optional regex flags (e.g., 'i' for case-insensitive, 'm' for multiline).\n */\n regexFlags?: string;\n};\n\nexport type BarcodeScannedEvent = { scannedCode: string; format: string };\n\n\nexport type RectangleDetectedEvent = {\n detected: true\n};\n\nexport type CapturePhotoOptions = {\n /**\n * The desired quality of the captured image, expressed as a value between 0.0 (lowest quality, smallest file size)\n * and 1.0 (highest quality, largest file size). Defaults to 1.0.\n * This parameter directly influences the compression level of the resulting JPEG image.\n */\n qualityRatio?: number;\n};\n\nexport type PermissionsResult = { camera: 'prompt' | 'denied' | 'granted' };\n\nexport type CapturePhotoResult = { imageBase64: string };\n\nexport type FlashResult = { enabled: boolean };\n\nexport type ZoomOptions = {\n /**\n * The zoom level to set. Must be 1, 2, or 3.\n * - 1 = 1.0x (no zoom)\n * - 2 = 2.0x\n * - 3 = 3.0x\n */\n level: 1 | 2 | 3;\n};\n\nexport type ZoomResult = { level: number };\n\nexport enum BarcodeFormat {\n Aztec = 'AZTEC',\n Code39 = 'CODE_39',\n Code93 = 'CODE_93',\n Code128 = 'CODE_128',\n DataMatrix = 'DATA_MATRIX',\n Ean8 = 'EAN_8',\n Ean13 = 'EAN_13',\n Itf14 = 'ITF14',\n Pdf417 = 'PDF_417',\n QrCode = 'QR_CODE',\n UpcE = 'UPC_E',\n}\n\ndeclare global {\n interface PluginRegistry {\n QRScanner: CapacitorScannerPlugin;\n }\n}"]}
|
|
@@ -39,6 +39,7 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
39
39
|
|
|
40
40
|
private let voteThreshold = 3
|
|
41
41
|
private var scannedCodesVotes = TTLMap<String, VoteStatus>(ttlSeconds: 5) // 5 second TTL
|
|
42
|
+
private var regexFilter: NSRegularExpression?
|
|
42
43
|
|
|
43
44
|
// for capturing images
|
|
44
45
|
private var photoOutput: AVCapturePhotoOutput?
|
|
@@ -58,7 +59,9 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
58
59
|
private var lastBarcodeDetectionTime: Date?
|
|
59
60
|
private let rectangleVisibilityTimeout: TimeInterval = 1.0 // Time in seconds before considering rectangle no longer visible
|
|
60
61
|
|
|
61
|
-
//
|
|
62
|
+
// Detection state (controls what detection runs)
|
|
63
|
+
private var enabledDetectionTypes: Set<String> = []
|
|
64
|
+
// Highlight state (controls what overlay is shown)
|
|
62
65
|
private var enabledHighlightTypes: Set<String> = []
|
|
63
66
|
private var overlayView: UIView?
|
|
64
67
|
private var barcodeOverlays: [CAShapeLayer] = []
|
|
@@ -119,10 +122,16 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
119
122
|
return
|
|
120
123
|
}
|
|
121
124
|
|
|
125
|
+
let showHighlight = call.getBool("showHighlight", true)
|
|
126
|
+
|
|
122
127
|
DispatchQueue.main.async {
|
|
123
|
-
// Add businessCard to enabled types
|
|
124
|
-
self.
|
|
125
|
-
|
|
128
|
+
// Add businessCard to enabled detection types
|
|
129
|
+
self.enabledDetectionTypes.insert("businessCard")
|
|
130
|
+
// Add to highlight types if showHighlight is true (default)
|
|
131
|
+
if showHighlight {
|
|
132
|
+
self.enabledHighlightTypes.insert("businessCard")
|
|
133
|
+
self.setupOverlayView()
|
|
134
|
+
}
|
|
126
135
|
|
|
127
136
|
call.resolve([
|
|
128
137
|
"enabled": true,
|
|
@@ -133,7 +142,8 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
133
142
|
|
|
134
143
|
@objc func disableObjectDetection(_ call: CAPPluginCall) {
|
|
135
144
|
DispatchQueue.main.async {
|
|
136
|
-
//
|
|
145
|
+
// Remove businessCard from both detection and highlight types
|
|
146
|
+
self.enabledDetectionTypes.remove("businessCard")
|
|
137
147
|
self.enabledHighlightTypes.remove("businessCard")
|
|
138
148
|
|
|
139
149
|
// Clear only businessCard overlay (not barcode overlay)
|
|
@@ -319,7 +329,7 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
319
329
|
self.capturePhotoCall = call
|
|
320
330
|
|
|
321
331
|
// If business card detection is enabled, wait for 1 second before capturing
|
|
322
|
-
if self.
|
|
332
|
+
if self.enabledDetectionTypes.contains("businessCard") {
|
|
323
333
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
|
|
324
334
|
photoOutput.capturePhoto(with: photoSettings, delegate: self)
|
|
325
335
|
}
|
|
@@ -341,7 +351,7 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
341
351
|
}
|
|
342
352
|
|
|
343
353
|
// Check if object detection is enabled and we have a detected rectangle with sufficient confidence
|
|
344
|
-
if self.
|
|
354
|
+
if self.enabledDetectionTypes.contains("businessCard"),
|
|
345
355
|
let detectedRect = self.lastDetectedRectangle { // Only use rectangles with sufficient confidence
|
|
346
356
|
// If we have a snapshot from the detection, use it directly
|
|
347
357
|
if let snapshot = detectedRect.snapshot {
|
|
@@ -514,6 +524,9 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
514
524
|
// Read detection options (defaults to false)
|
|
515
525
|
let enableBarcodeDetection = call.getBool("barcodeDetection", false)
|
|
516
526
|
let enableObjectDetection = call.getBool("objectDetection", false)
|
|
527
|
+
// Read highlight options (barcode defaults to false, businessCard defaults to true)
|
|
528
|
+
let enableBarcodeHighlight = call.getBool("barcodeHighlight", false)
|
|
529
|
+
let enableObjectHighlight = call.getBool("objectHighlight", true)
|
|
517
530
|
|
|
518
531
|
DispatchQueue.main.async {
|
|
519
532
|
// Stop any existing session first (must be on main thread for UI operations)
|
|
@@ -525,12 +538,35 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
525
538
|
|
|
526
539
|
// Enable barcode detection if requested
|
|
527
540
|
if enableBarcodeDetection {
|
|
528
|
-
self.
|
|
541
|
+
self.enabledDetectionTypes.insert("barcode")
|
|
542
|
+
if enableBarcodeHighlight {
|
|
543
|
+
self.enabledHighlightTypes.insert("barcode")
|
|
544
|
+
}
|
|
529
545
|
}
|
|
530
546
|
|
|
531
547
|
// Enable object detection (businessCard) if requested
|
|
532
548
|
if enableObjectDetection {
|
|
533
|
-
self.
|
|
549
|
+
self.enabledDetectionTypes.insert("businessCard")
|
|
550
|
+
if enableObjectHighlight {
|
|
551
|
+
self.enabledHighlightTypes.insert("businessCard")
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Handle Regex Filter
|
|
556
|
+
if let pattern = call.getString("regex") {
|
|
557
|
+
let flags = call.getString("regexFlags") ?? ""
|
|
558
|
+
var options: NSRegularExpression.Options = []
|
|
559
|
+
if flags.contains("i") { options.insert(.caseInsensitive) }
|
|
560
|
+
if flags.contains("m") { options.insert(.anchorsMatchLines) }
|
|
561
|
+
|
|
562
|
+
do {
|
|
563
|
+
self.regexFilter = try NSRegularExpression(pattern: pattern, options: options)
|
|
564
|
+
} catch {
|
|
565
|
+
call.reject("Invalid Regex pattern")
|
|
566
|
+
return
|
|
567
|
+
}
|
|
568
|
+
} else {
|
|
569
|
+
self.regexFilter = nil
|
|
534
570
|
}
|
|
535
571
|
|
|
536
572
|
// Start monitoring device motion
|
|
@@ -644,12 +680,15 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
644
680
|
self.videoDataOutput = nil
|
|
645
681
|
self.currentPixelBuffer = nil
|
|
646
682
|
self.scannedCodesVotes.clear()
|
|
647
|
-
self.
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
683
|
+
self.regexFilter = nil
|
|
684
|
+
self.clearAllOverlays()
|
|
685
|
+
self.showWebViewBackground()
|
|
686
|
+
self.enabledDetectionTypes.removeAll()
|
|
687
|
+
self.enabledHighlightTypes.removeAll()
|
|
688
|
+
self.lastRectangleDetectionTime = nil
|
|
689
|
+
self.lastBarcodeDetectionTime = nil
|
|
690
|
+
self.removeOrientationChangeObserver()
|
|
691
|
+
|
|
653
692
|
}
|
|
654
693
|
|
|
655
694
|
private func addOrientationChangeObserver() {
|
|
@@ -818,9 +857,16 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
818
857
|
return
|
|
819
858
|
}
|
|
820
859
|
|
|
821
|
-
// First find the barcode with highest confidence
|
|
860
|
+
// First find the barcode with highest confidence that matches the regex (if provided)
|
|
822
861
|
let highestConfidenceBarcode = observations
|
|
823
|
-
.filter {
|
|
862
|
+
.filter { observation in
|
|
863
|
+
guard let payload = observation.payloadStringValue else { return false }
|
|
864
|
+
if let regex = self.regexFilter {
|
|
865
|
+
let range = NSRange(location: 0, length: payload.utf16.count)
|
|
866
|
+
return regex.firstMatch(in: payload, options: [], range: range) != nil
|
|
867
|
+
}
|
|
868
|
+
return true
|
|
869
|
+
}
|
|
824
870
|
.max(by: { $0.confidence < $1.confidence })
|
|
825
871
|
|
|
826
872
|
// Then process only that barcode if found
|
|
@@ -1045,9 +1091,14 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
1045
1091
|
}
|
|
1046
1092
|
|
|
1047
1093
|
@objc func enableBarcodeDetection(_ call: CAPPluginCall) {
|
|
1094
|
+
let showHighlight = call.getBool("showHighlight", false)
|
|
1095
|
+
|
|
1048
1096
|
DispatchQueue.main.async {
|
|
1049
|
-
self.
|
|
1050
|
-
|
|
1097
|
+
self.enabledDetectionTypes.insert("barcode")
|
|
1098
|
+
if showHighlight {
|
|
1099
|
+
self.enabledHighlightTypes.insert("barcode")
|
|
1100
|
+
self.setupOverlayView()
|
|
1101
|
+
}
|
|
1051
1102
|
|
|
1052
1103
|
call.resolve([
|
|
1053
1104
|
"enabled": true,
|
|
@@ -1057,6 +1108,7 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
1057
1108
|
|
|
1058
1109
|
@objc func disableBarcodeDetection(_ call: CAPPluginCall) {
|
|
1059
1110
|
DispatchQueue.main.async {
|
|
1111
|
+
self.enabledDetectionTypes.remove("barcode")
|
|
1060
1112
|
self.enabledHighlightTypes.remove("barcode")
|
|
1061
1113
|
|
|
1062
1114
|
// Clear cached barcodes
|
|
@@ -1150,12 +1202,12 @@ extension CapacitorScannerPlugin: AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
|
1150
1202
|
var requests: [VNRequest] = []
|
|
1151
1203
|
|
|
1152
1204
|
// Only include barcode detection if enabled
|
|
1153
|
-
if self.
|
|
1205
|
+
if self.enabledDetectionTypes.contains("barcode") {
|
|
1154
1206
|
requests.append(self.barcodeDetectionRequest)
|
|
1155
1207
|
}
|
|
1156
1208
|
|
|
1157
|
-
// Add rectangle detection if business card
|
|
1158
|
-
if self.
|
|
1209
|
+
// Add rectangle detection if business card detection is enabled
|
|
1210
|
+
if self.enabledDetectionTypes.contains("businessCard") {
|
|
1159
1211
|
requests.append(self.rectangleDetectionRequest)
|
|
1160
1212
|
}
|
|
1161
1213
|
|