@trustchex/react-native-sdk 1.362.6 → 1.381.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/TrustchexSDK.podspec +3 -3
- package/android/build.gradle +3 -3
- package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +64 -19
- package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +636 -301
- package/ios/Camera/TrustchexCameraView.swift +166 -119
- package/ios/OpenCV/OpenCVHelper.h +0 -7
- package/ios/OpenCV/OpenCVHelper.mm +0 -60
- package/ios/OpenCV/OpenCVModule.h +0 -4
- package/ios/OpenCV/OpenCVModule.mm +440 -358
- package/lib/module/Shared/Components/DebugOverlay.js +541 -0
- package/lib/module/Shared/Components/FaceCamera.js +1 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +44 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +270 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +708 -1593
- package/lib/module/Shared/Components/IdentityDocumentCamera.types.js +3 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +273 -0
- package/lib/module/Shared/Components/QrCodeScannerCamera.js +1 -8
- package/lib/module/Shared/Libs/mrz.utils.js +202 -9
- package/lib/module/Translation/Resources/en.js +0 -4
- package/lib/module/Translation/Resources/tr.js +0 -4
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts +30 -0
- package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/FaceCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts +35 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -56
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +88 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts +116 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +93 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/QrCodeScannerCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts +1 -0
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts +8 -0
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/en.d.ts +0 -4
- package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/tr.d.ts +0 -4
- package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Shared/Components/DebugOverlay.tsx +656 -0
- package/src/Shared/Components/FaceCamera.tsx +1 -0
- package/src/Shared/Components/IdentityDocumentCamera.constants.ts +44 -0
- package/src/Shared/Components/IdentityDocumentCamera.flows.ts +342 -0
- package/src/Shared/Components/IdentityDocumentCamera.tsx +1105 -2324
- package/src/Shared/Components/IdentityDocumentCamera.types.ts +136 -0
- package/src/Shared/Components/IdentityDocumentCamera.utils.ts +364 -0
- package/src/Shared/Components/QrCodeScannerCamera.tsx +1 -9
- package/src/Shared/Components/TrustchexCamera.tsx +1 -0
- package/src/Shared/Libs/mrz.utils.ts +238 -26
- package/src/Translation/Resources/en.ts +0 -4
- package/src/Translation/Resources/tr.ts +0 -4
- package/src/version.ts +1 -1
package/TrustchexSDK.podspec
CHANGED
|
@@ -19,9 +19,9 @@ Pod::Spec.new do |s|
|
|
|
19
19
|
s.public_header_files = "ios/OpenCV/OpenCVHelper.h"
|
|
20
20
|
|
|
21
21
|
# ML Kit dependencies
|
|
22
|
-
s.dependency "GoogleMLKit/TextRecognition"
|
|
23
|
-
s.dependency "GoogleMLKit/FaceDetection"
|
|
24
|
-
s.dependency "GoogleMLKit/BarcodeScanning"
|
|
22
|
+
s.dependency "GoogleMLKit/TextRecognition", "~> 9.0"
|
|
23
|
+
s.dependency "GoogleMLKit/FaceDetection", "~> 9.0"
|
|
24
|
+
s.dependency "GoogleMLKit/BarcodeScanning", "~> 9.0"
|
|
25
25
|
|
|
26
26
|
# OpenCV dependency
|
|
27
27
|
s.dependency "OpenCV", "~> 4.3.0"
|
package/android/build.gradle
CHANGED
|
@@ -83,9 +83,9 @@ dependencies {
|
|
|
83
83
|
implementation "androidx.camera:camera-video:1.4.0"
|
|
84
84
|
|
|
85
85
|
// Google ML Kit dependencies
|
|
86
|
-
implementation 'com.google.mlkit:text-recognition:16.0.
|
|
87
|
-
implementation 'com.google.mlkit:face-detection:16.1.
|
|
88
|
-
implementation 'com.google.mlkit:barcode-scanning:17.
|
|
86
|
+
implementation 'com.google.mlkit:text-recognition:16.0.0'
|
|
87
|
+
implementation 'com.google.mlkit:face-detection:16.1.5'
|
|
88
|
+
implementation 'com.google.mlkit:barcode-scanning:17.1.0'
|
|
89
89
|
|
|
90
90
|
// Google Play Services dependency for Tasks
|
|
91
91
|
implementation 'com.google.android.gms:play-services-tasks:18.2.0'
|
|
@@ -44,10 +44,10 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
44
44
|
// ==================================================================================
|
|
45
45
|
// PORTRAIT-ONLY CAMERA VIEW
|
|
46
46
|
// All camera use cases are locked to ROTATION_0 (portrait) orientation.
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
47
|
+
// Supports two resolutions:
|
|
48
|
+
// - HD: 720x1280 (portrait HD) - lower bandwidth, faster processing
|
|
49
|
+
// - Full HD: 1080x1920 (portrait Full HD, default) - sharp text/document capture
|
|
50
|
+
// Selection criteria: use Full HD for document scanning, HD for real-time detection
|
|
51
51
|
// Activity must be locked to portrait in AndroidManifest.xml
|
|
52
52
|
// ==================================================================================
|
|
53
53
|
|
|
@@ -69,6 +69,7 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
69
69
|
private var torchEnabled = false
|
|
70
70
|
private var frameProcessingEnabled = false
|
|
71
71
|
private var targetFps = 10
|
|
72
|
+
private var resolution = "fullhd" // "hd" (720x1280) or "fullhd" (1080x1920, default)
|
|
72
73
|
private var isCameraInitialized = false
|
|
73
74
|
private var isStoppingRecording = false // Track if stopRecording was called to prevent cancelRecording from deleting the file
|
|
74
75
|
|
|
@@ -80,6 +81,8 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
80
81
|
|
|
81
82
|
// ML Kit detector instances (lazy, created once)
|
|
82
83
|
private val textRecognizer by lazy {
|
|
84
|
+
// Use DEFAULT_OPTIONS for best accuracy with Latin scripts (including MRZ)
|
|
85
|
+
// ML Kit Text Recognition v2 provides superior accuracy for document scanning
|
|
83
86
|
TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
|
|
84
87
|
}
|
|
85
88
|
private val faceDetector by lazy {
|
|
@@ -202,6 +205,14 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
202
205
|
targetFps = fps.coerceIn(1, 30)
|
|
203
206
|
}
|
|
204
207
|
|
|
208
|
+
fun setResolution(res: String) {
|
|
209
|
+
// Accept "hd" or "fullhd" (default "fullhd" for 1080x1920)
|
|
210
|
+
resolution = if (res.lowercase() == "hd") "hd" else "fullhd"
|
|
211
|
+
if (isCameraInitialized) {
|
|
212
|
+
initializeCamera()
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
205
216
|
fun setFaceDetectionEnabled(enabled: Boolean) {
|
|
206
217
|
faceDetectionEnabled = enabled
|
|
207
218
|
}
|
|
@@ -238,14 +249,12 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
238
249
|
provider.unbindAll()
|
|
239
250
|
|
|
240
251
|
try {
|
|
241
|
-
// Determine resolution based on
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
val
|
|
245
|
-
|
|
246
|
-
Size(
|
|
247
|
-
} else {
|
|
248
|
-
Size(1080, 1920) // Portrait Full HD for back camera
|
|
252
|
+
// Determine resolution based on configured resolution setting
|
|
253
|
+
// "hd": 720x1280 (lower bandwidth, faster processing)
|
|
254
|
+
// "fullhd": 1080x1920 (default - sharp text/document capture)
|
|
255
|
+
val targetResolution = when (resolution.lowercase()) {
|
|
256
|
+
"hd" -> Size(720, 1280) // Portrait HD
|
|
257
|
+
else -> Size(1080, 1920) // Portrait Full HD (default)
|
|
249
258
|
}
|
|
250
259
|
|
|
251
260
|
// Preview use case
|
|
@@ -273,9 +282,13 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
273
282
|
// Removing it allows us to bind VideoCapture + Analyzer + Preview simultaneously
|
|
274
283
|
// within the 3-use-case limit of many Android devices.
|
|
275
284
|
|
|
276
|
-
// Video capture use case —
|
|
285
|
+
// Video capture use case — select quality based on resolution setting
|
|
286
|
+
val videoQuality = when (resolution.lowercase()) {
|
|
287
|
+
"hd" -> Quality.HD // 720x1280
|
|
288
|
+
else -> Quality.FHD // 1080x1920 (Full HD, default)
|
|
289
|
+
}
|
|
277
290
|
val recorder = Recorder.Builder()
|
|
278
|
-
.setQualitySelector(QualitySelector.from(
|
|
291
|
+
.setQualitySelector(QualitySelector.from(videoQuality))
|
|
279
292
|
.build()
|
|
280
293
|
videoCapture = VideoCapture.withOutput(recorder)
|
|
281
294
|
|
|
@@ -351,6 +364,12 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
351
364
|
return
|
|
352
365
|
}
|
|
353
366
|
|
|
367
|
+
// ML Kit Performance Optimization Tips Applied:
|
|
368
|
+
// 1. Throttle detector calls using STRATEGY_KEEP_ONLY_LATEST backpressure
|
|
369
|
+
// 2. Drop frames if detector is still busy (prevents queue buildup)
|
|
370
|
+
// 3. Process at lower resolution (720x1280 portrait) for real-time detection
|
|
371
|
+
// 4. Use ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST for frame dropping
|
|
372
|
+
// 5. Close ImageProxy immediately after ML Kit processing completes
|
|
354
373
|
val hasAnyDetection = frameProcessingEnabled && (faceDetectionEnabled || textRecognitionEnabled || barcodeScanningEnabled)
|
|
355
374
|
if (!hasAnyDetection) {
|
|
356
375
|
isProcessing.set(false)
|
|
@@ -363,9 +382,6 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
363
382
|
|
|
364
383
|
// Create InputImage directly from camera frame — zero-copy, no base64 for ML Kit
|
|
365
384
|
val inputImage = InputImage.fromMediaImage(mediaImage, rotationDegrees)
|
|
366
|
-
|
|
367
|
-
// Use original image for text recognition
|
|
368
|
-
val textInputImage = inputImage
|
|
369
385
|
|
|
370
386
|
// Calculate portrait-oriented dimensions early (JPEG is already rotated)
|
|
371
387
|
val isRotated = rotationDegrees == 90 || rotationDegrees == 270
|
|
@@ -376,6 +392,10 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
376
392
|
// Brightness calculation restricted to scanning frame area (between 36% from top and 36% from bottom, 5% margins on sides)
|
|
377
393
|
val averageBrightness = computeYPlaneBrightness(imageProxy, reportedWidth, reportedHeight)
|
|
378
394
|
|
|
395
|
+
// Use original inputImage directly for text recognition
|
|
396
|
+
// ML Kit works best with native camera frames, not processed bitmaps
|
|
397
|
+
val textInputImage = inputImage
|
|
398
|
+
|
|
379
399
|
// Generate JPEG base64 only when JS side explicitly needs the image
|
|
380
400
|
// NOTE: Do NOT auto-generate for face detection - too expensive, causes frame drops
|
|
381
401
|
val jpegBase64: String? = if (includeBase64) {
|
|
@@ -398,6 +418,7 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
398
418
|
} else null
|
|
399
419
|
|
|
400
420
|
// Wait for all detectors, then build + send a single event to JS
|
|
421
|
+
// ML Kit resource cleanup: InputImage is automatically cleaned after task completion
|
|
401
422
|
Tasks.whenAllComplete(tasks).addOnCompleteListener { _ ->
|
|
402
423
|
try {
|
|
403
424
|
val frameData = Arguments.createMap()
|
|
@@ -476,8 +497,6 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
476
497
|
}
|
|
477
498
|
}
|
|
478
499
|
|
|
479
|
-
// MRZ validation moved to JavaScript - native implementation removed
|
|
480
|
-
|
|
481
500
|
// Barcode scanning results
|
|
482
501
|
if (barcodeTask != null) {
|
|
483
502
|
val barcodesArray = Arguments.createArray()
|
|
@@ -581,6 +600,32 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
|
|
|
581
600
|
return if (count > 0) sum.toDouble() / count else 0.0
|
|
582
601
|
}
|
|
583
602
|
|
|
603
|
+
/**
|
|
604
|
+
* Validates if the image dimensions are suitable for ML Kit text recognition.
|
|
605
|
+
*
|
|
606
|
+
* ML Kit text recognition requirements:
|
|
607
|
+
* - Minimum 16x16 pixels per character for acceptable accuracy
|
|
608
|
+
* - Ideal: 16-24 pixels per character for optimal performance
|
|
609
|
+
* - At 720x1280 (portrait HD), assuming ~30px average character width:
|
|
610
|
+
* - Can fit ~24 characters per line (720/30)
|
|
611
|
+
* - Can fit ~42 lines (1280/30)
|
|
612
|
+
*
|
|
613
|
+
* @return quality score (0.0-1.0) where 1.0 is optimal
|
|
614
|
+
*/
|
|
615
|
+
private fun calculateTextRecognitionQuality(width: Int, height: Int): Double {
|
|
616
|
+
// For text at typical font sizes, we want at least 720px width
|
|
617
|
+
// Quality decreases significantly below 640px
|
|
618
|
+
val pixelScore = when {
|
|
619
|
+
width >= 720 && height >= 1280 -> 1.0 // Optimal
|
|
620
|
+
width >= 640 && height >= 960 -> 0.85 // Good
|
|
621
|
+
width >= 480 && height >= 640 -> 0.65 // Acceptable
|
|
622
|
+
else -> 0.4 // Poor
|
|
623
|
+
}
|
|
624
|
+
return pixelScore
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
584
629
|
private fun yuvImageProxyToJpegBase64(imageProxy: ImageProxy, rotationDegrees: Int): String? {
|
|
585
630
|
try {
|
|
586
631
|
val width = imageProxy.width
|