@scr2em/capacitor-scanner 6.0.30 → 6.0.31
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 +1 -1
- package/android/src/main/java/com/leadliaion/capacitorscanner/CapacitorScannerPlugin.java +39 -1
- package/dist/docs.json +1 -1
- package/dist/esm/definitions.d.ts +7 -0
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/CapacitorScannerPlugin/CapacitorScannerPlugin.swift +21 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -262,7 +262,7 @@ Set the camera zoom level.
|
|
|
262
262
|
|
|
263
263
|
#### StartOptions
|
|
264
264
|
|
|
265
|
-
<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; /** * Minimum interval in seconds between consecutive 'rectangleDetected' events. * Only applies when objectDetection is true. * Defaults to 0 (no throttling beyond initial stability check). */ rectangleEmitIntervalSeconds?: 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>
|
|
265
|
+
<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; /** * Minimum interval in seconds between consecutive 'rectangleDetected' events. * Only applies when objectDetection is true. * Defaults to 0 (no throttling beyond initial stability check). */ rectangleEmitIntervalSeconds?: 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; /** * Duration in seconds to pause rectangle detection after a barcode is successfully scanned. * When both barcode and object detection are enabled, this gives barcode scanning priority * by temporarily suppressing rectangle detection after a barcode is emitted. * Defaults to 0 (no throttle, both detections run simultaneously). */ detectionThrottleSeconds?: number; }</code>
|
|
266
266
|
|
|
267
267
|
|
|
268
268
|
#### CapturePhotoOptions
|
|
@@ -143,6 +143,10 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
143
143
|
// Configurable interval between rectangle detection event emissions (in milliseconds)
|
|
144
144
|
private long rectangleEmitIntervalMs = 0; // Default: 0 (no throttling)
|
|
145
145
|
|
|
146
|
+
// Detection throttle: pause rectangle detection after a successful barcode scan
|
|
147
|
+
private long detectionThrottleMs = 0; // Default: 0 (no throttle)
|
|
148
|
+
private long lastSuccessfulBarcodeScanTime = 0;
|
|
149
|
+
|
|
146
150
|
/**
|
|
147
151
|
* Calculates the processing interval in milliseconds based on the desired
|
|
148
152
|
* frequency per second.
|
|
@@ -230,6 +234,19 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
230
234
|
}
|
|
231
235
|
}
|
|
232
236
|
|
|
237
|
+
// Read detection throttle
|
|
238
|
+
if (call.getData().has("detectionThrottleSeconds")) {
|
|
239
|
+
try {
|
|
240
|
+
double throttleSeconds = call.getData().getDouble("detectionThrottleSeconds");
|
|
241
|
+
detectionThrottleMs = Math.max(0, (long) (throttleSeconds * 1000));
|
|
242
|
+
} catch (Exception e) {
|
|
243
|
+
detectionThrottleMs = 0;
|
|
244
|
+
}
|
|
245
|
+
} else {
|
|
246
|
+
detectionThrottleMs = 0;
|
|
247
|
+
}
|
|
248
|
+
lastSuccessfulBarcodeScanTime = 0;
|
|
249
|
+
|
|
233
250
|
try {
|
|
234
251
|
String cameraDirectionStr = call.getString("cameraDirection", "BACK");
|
|
235
252
|
int lensFacing;
|
|
@@ -465,7 +482,22 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
465
482
|
InputImage image = InputImage.fromMediaImage(mediaImage, rotationDegrees);
|
|
466
483
|
|
|
467
484
|
boolean barcodeEnabled = scanner != null && enabledDetectionTypes.contains("barcode");
|
|
468
|
-
boolean
|
|
485
|
+
boolean isRectangleThrottled = detectionThrottleMs > 0
|
|
486
|
+
&& lastSuccessfulBarcodeScanTime > 0
|
|
487
|
+
&& (System.currentTimeMillis() - lastSuccessfulBarcodeScanTime) < detectionThrottleMs;
|
|
488
|
+
boolean rectangleEnabled = rectangleDetector != null
|
|
489
|
+
&& enabledDetectionTypes.contains("businessCard")
|
|
490
|
+
&& !isRectangleThrottled;
|
|
491
|
+
|
|
492
|
+
// Clear rectangle overlay when throttled
|
|
493
|
+
if (isRectangleThrottled && enabledDetectionTypes.contains("businessCard")) {
|
|
494
|
+
getActivity().runOnUiThread(() -> {
|
|
495
|
+
synchronized (overlayLock) {
|
|
496
|
+
currentRectangleRects.clear();
|
|
497
|
+
updateOverlayDetections(currentBarcodeRects, currentRectangleRects);
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
469
501
|
|
|
470
502
|
// Rectangle detection (synchronous) - runs first while imageProxy is still open
|
|
471
503
|
if (rectangleEnabled) {
|
|
@@ -876,6 +908,10 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
876
908
|
data.put("scannedCode", rawValue);
|
|
877
909
|
data.put("format", BarcodeFormatHelper.barcodeFormatToString(format));
|
|
878
910
|
notifyListeners("barcodeScanned", data, true);
|
|
911
|
+
|
|
912
|
+
// Record successful scan time for detection throttle
|
|
913
|
+
lastSuccessfulBarcodeScanTime = System.currentTimeMillis();
|
|
914
|
+
|
|
879
915
|
echo("Barcode " + rawValue + " scanned with format: "
|
|
880
916
|
+ BarcodeFormatHelper.barcodeFormatToString(format));
|
|
881
917
|
}
|
|
@@ -1150,6 +1186,8 @@ public class CapacitorScannerPlugin extends Plugin {
|
|
|
1150
1186
|
lastRectangleProcessingTime = 0;
|
|
1151
1187
|
lastRectangleDetectionTime = 0;
|
|
1152
1188
|
rectangleEmitIntervalMs = 0;
|
|
1189
|
+
detectionThrottleMs = 0;
|
|
1190
|
+
lastSuccessfulBarcodeScanTime = 0;
|
|
1153
1191
|
|
|
1154
1192
|
// Clear detection histories and caches
|
|
1155
1193
|
enabledDetectionTypes.clear();
|
package/dist/docs.json
CHANGED
|
@@ -344,7 +344,7 @@
|
|
|
344
344
|
"docs": "",
|
|
345
345
|
"types": [
|
|
346
346
|
{
|
|
347
|
-
"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 /**\n * Minimum interval in seconds between consecutive 'rectangleDetected' events.\n * Only applies when objectDetection is true.\n * Defaults to 0 (no throttling beyond initial stability check).\n */\n rectangleEmitIntervalSeconds?: 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}",
|
|
347
|
+
"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 /**\n * Minimum interval in seconds between consecutive 'rectangleDetected' events.\n * Only applies when objectDetection is true.\n * Defaults to 0 (no throttling beyond initial stability check).\n */\n rectangleEmitIntervalSeconds?: 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 * Duration in seconds to pause rectangle detection after a barcode is successfully scanned.\n * When both barcode and object detection are enabled, this gives barcode scanning priority\n * by temporarily suppressing rectangle detection after a barcode is emitted.\n * Defaults to 0 (no throttle, both detections run simultaneously).\n */\n detectionThrottleSeconds?: number;\n}",
|
|
348
348
|
"complexTypes": [
|
|
349
349
|
"BarcodeFormat"
|
|
350
350
|
]
|
|
@@ -114,6 +114,13 @@ export declare type StartOptions = {
|
|
|
114
114
|
* Optional regex flags (e.g., 'i' for case-insensitive, 'm' for multiline).
|
|
115
115
|
*/
|
|
116
116
|
regexFlags?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Duration in seconds to pause rectangle detection after a barcode is successfully scanned.
|
|
119
|
+
* When both barcode and object detection are enabled, this gives barcode scanning priority
|
|
120
|
+
* by temporarily suppressing rectangle detection after a barcode is emitted.
|
|
121
|
+
* Defaults to 0 (no throttle, both detections run simultaneously).
|
|
122
|
+
*/
|
|
123
|
+
detectionThrottleSeconds?: number;
|
|
117
124
|
};
|
|
118
125
|
export declare type BarcodeScannedEvent = {
|
|
119
126
|
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":"AAyKA,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 /**\n * Enable object detection (business card). This will start detecting business cards.\n * @param options - Optional configuration for object detection\n */\n enableObjectDetection(options?: ObjectDetectionOptions): Promise<{ enabled: true }>;\n\n /**\n * Disable object detection. This will stop detecting business cards.\n */\n disableObjectDetection(): Promise<{ enabled: false }>;\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 * Whether to show the highlight overlay for detected business cards.\n * Defaults to true.\n */\n showHighlight?: boolean,\n /**\n * Minimum interval in seconds between consecutive 'rectangleDetected' events.\n * After an event is emitted, no new events will be emitted until this interval passes.\n * Set to 0 to emit events as soon as stability is detected.\n * Defaults to 0 (no throttling beyond initial stability check).\n */\n emitIntervalSeconds?: number\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 /**\n * Minimum interval in seconds between consecutive 'rectangleDetected' events.\n * Only applies when objectDetection is true.\n * Defaults to 0 (no throttling beyond initial stability check).\n */\n rectangleEmitIntervalSeconds?: 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 * Duration in seconds to pause rectangle detection after a barcode is successfully scanned.\n * When both barcode and object detection are enabled, this gives barcode scanning priority\n * by temporarily suppressing rectangle detection after a barcode is emitted.\n * Defaults to 0 (no throttle, both detections run simultaneously).\n */\n detectionThrottleSeconds?: number;\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}"]}
|
|
@@ -51,6 +51,10 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
51
51
|
private var lastBarcodeDetectionTime: Date?
|
|
52
52
|
private let barcodeVisibilityTimeout: TimeInterval = 1.0
|
|
53
53
|
|
|
54
|
+
// Detection throttle: pause rectangle detection after a successful barcode scan
|
|
55
|
+
private var detectionThrottleSeconds: TimeInterval = 0
|
|
56
|
+
private var lastSuccessfulBarcodeScanTime: Date?
|
|
57
|
+
|
|
54
58
|
// Detection state (controls what detection runs)
|
|
55
59
|
private var enabledDetectionTypes: Set<String> = []
|
|
56
60
|
// Highlight state (controls what overlay is shown)
|
|
@@ -464,6 +468,10 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
464
468
|
self.rectangleDetector?.setEmitInterval(emitInterval)
|
|
465
469
|
}
|
|
466
470
|
|
|
471
|
+
// Read detection throttle
|
|
472
|
+
self.detectionThrottleSeconds = call.getDouble("detectionThrottleSeconds") ?? 0
|
|
473
|
+
self.lastSuccessfulBarcodeScanTime = nil
|
|
474
|
+
|
|
467
475
|
// Handle Regex Filter
|
|
468
476
|
if let pattern = call.getString("regex") {
|
|
469
477
|
let flags = call.getString("regexFlags") ?? ""
|
|
@@ -596,6 +604,8 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
596
604
|
self.enabledDetectionTypes.removeAll()
|
|
597
605
|
self.enabledHighlightTypes.removeAll()
|
|
598
606
|
self.lastBarcodeDetectionTime = nil
|
|
607
|
+
self.lastSuccessfulBarcodeScanTime = nil
|
|
608
|
+
self.detectionThrottleSeconds = 0
|
|
599
609
|
self.removeOrientationChangeObserver()
|
|
600
610
|
}
|
|
601
611
|
|
|
@@ -811,6 +821,9 @@ public class CapacitorScannerPlugin: CAPPlugin, CAPBridgedPlugin, AVCaptureMetad
|
|
|
811
821
|
"format": CapacitorScannerHelpers.convertBarcodeScannerFormatToString(bestObservation.symbology),
|
|
812
822
|
])
|
|
813
823
|
|
|
824
|
+
// Record successful scan time for detection throttle
|
|
825
|
+
self.lastSuccessfulBarcodeScanTime = Date()
|
|
826
|
+
|
|
814
827
|
// Reset votes after successful scan
|
|
815
828
|
self.scannedCodesVotes.clear()
|
|
816
829
|
}
|
|
@@ -1024,7 +1037,14 @@ extension CapacitorScannerPlugin: AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
|
1024
1037
|
requests.append(self.barcodeDetectionRequest)
|
|
1025
1038
|
}
|
|
1026
1039
|
|
|
1027
|
-
|
|
1040
|
+
let isRectangleThrottled: Bool = {
|
|
1041
|
+
guard self.detectionThrottleSeconds > 0,
|
|
1042
|
+
let lastScan = self.lastSuccessfulBarcodeScanTime else { return false }
|
|
1043
|
+
return Date().timeIntervalSince(lastScan) < self.detectionThrottleSeconds
|
|
1044
|
+
}()
|
|
1045
|
+
|
|
1046
|
+
if !isRectangleThrottled,
|
|
1047
|
+
self.enabledDetectionTypes.contains("businessCard"),
|
|
1028
1048
|
let detector = self.rectangleDetector {
|
|
1029
1049
|
detector.updatePixelBuffer(pixelBuffer)
|
|
1030
1050
|
requests.append(detector.visionRequest)
|