react-native-vision-camera-spoof-detector 1.0.6 → 1.0.7
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/android/.cxx/Debug/2a1it684/arm64-v8a/.cmake/api/v1/reply/{codemodel-v2-6c7de80461af72f456a3.json → codemodel-v2-390962e2784a6a84fa3e.json} +2 -2
- package/android/.cxx/Debug/2a1it684/arm64-v8a/.cmake/api/v1/reply/{index-2025-11-24T17-41-56-0411.json → index-2025-11-25T14-48-56-0722.json} +2 -2
- package/android/.cxx/Debug/2a1it684/arm64-v8a/.cmake/api/v1/reply/{target-yuv-Debug-32bc4eddd343848e1c25.json → target-yuv-Debug-1e27b8a2bdcddd47b87d.json} +4 -4
- package/android/.cxx/Debug/2a1it684/arm64-v8a/.cmake/api/v1/reply/{target-yuv_shared-Debug-75ea769bf76a12914d29.json → target-yuv_shared-Debug-ac9194487d1fc1268a87.json} +4 -4
- package/android/.cxx/Debug/2a1it684/arm64-v8a/.ninja_deps +0 -0
- package/android/.cxx/Debug/2a1it684/arm64-v8a/.ninja_log +125 -125
- package/android/.cxx/Debug/2a1it684/arm64-v8a/CMakeFiles/CMakeOutput.log +22 -22
- package/android/.cxx/Debug/2a1it684/arm64-v8a/configure_fingerprint.bin +15 -15
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/.cmake/api/v1/reply/{codemodel-v2-053850119b681f93cecc.json → codemodel-v2-52ac1d8b40b69596389b.json} +2 -2
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/.cmake/api/v1/reply/{index-2025-11-18T18-09-57-0510.json → index-2025-11-25T14-14-30-0191.json} +2 -2
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/.cmake/api/v1/reply/{target-yuv-Debug-a12ad49ff79080871bce.json → target-yuv-Debug-97f9e822dbd84a186d44.json} +2 -2
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/.cmake/api/v1/reply/{target-yuv_shared-Debug-2b00e64621a56b8dd632.json → target-yuv_shared-Debug-3730d20e27c3481c06b2.json} +2 -2
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/.ninja_deps +0 -0
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/.ninja_log +117 -118
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/CMakeFiles/CMakeOutput.log +20 -20
- package/android/.cxx/Debug/2a1it684/armeabi-v7a/configure_fingerprint.bin +15 -15
- package/android/.cxx/Debug/2a1it684/x86/.ninja_deps +0 -0
- package/android/.cxx/Debug/2a1it684/x86/.ninja_log +109 -110
- package/android/.cxx/Debug/2a1it684/x86/CMakeFiles/CMakeOutput.log +20 -20
- package/android/.cxx/Debug/2a1it684/x86/configure_fingerprint.bin +15 -15
- package/android/.cxx/Debug/2a1it684/x86_64/.ninja_deps +0 -0
- package/android/.cxx/Debug/2a1it684/x86_64/.ninja_log +109 -109
- package/android/.cxx/Debug/2a1it684/x86_64/CMakeFiles/CMakeOutput.log +20 -20
- package/android/.cxx/Debug/2a1it684/x86_64/configure_fingerprint.bin +15 -15
- package/android/build/.transforms/4ebf3dd0dca4f83fe1776360e21ded81/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/c0a07cd9442d741ad3cef3760159211f/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/faceantispoof/AntiSpoofingResult.dex +0 -0
- package/android/build/.transforms/c0a07cd9442d741ad3cef3760159211f/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/faceantispoof/FaceAntiSpoofFrameProcessor.dex +0 -0
- package/android/build/.transforms/c0a07cd9442d741ad3cef3760159211f/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/faceantispoof/FaceAntiSpoofingAdvanced$SpoofDetectionResult.dex +0 -0
- package/android/build/.transforms/c0a07cd9442d741ad3cef3760159211f/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/faceantispoof/FaceAntiSpoofingAdvanced.dex +0 -0
- package/android/build/.transforms/c0a07cd9442d741ad3cef3760159211f/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/faceantispoof/ImageFormatEncoder$ImageFormat.dex +0 -0
- package/android/build/.transforms/c0a07cd9442d741ad3cef3760159211f/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/faceantispoof/ImageFormatEncoder.dex +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/arm64-v8a/build_stdout_targets.txt +51 -51
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/arm64-v8a/generate_cxx_metadata_456_timing.txt +9 -0
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/armeabi-v7a/build_stdout_targets.txt +52 -52
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/armeabi-v7a/{generate_cxx_metadata_2687_timing.txt → generate_cxx_metadata_455_timing.txt} +1 -1
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/x86/build_stdout_targets.txt +36 -36
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/x86/{generate_cxx_metadata_2687_timing.txt → generate_cxx_metadata_455_timing.txt} +1 -1
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/x86_64/build_stdout_targets.txt +46 -46
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/x86_64/generate_cxx_metadata_455_timing.txt +9 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/faceantispoof/AntiSpoofingResult.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/faceantispoof/FaceAntiSpoofFrameProcessor.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/faceantispoof/FaceAntiSpoofingAdvanced$SpoofDetectionResult.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/faceantispoof/FaceAntiSpoofingAdvanced.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/faceantispoof/ImageFormatEncoder$ImageFormat.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/faceantispoof/ImageFormatEncoder.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/AntiSpoofingResult.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/FaceAntiSpoofFrameProcessor.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/FaceAntiSpoofingAdvanced$SpoofDetectionResult.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/FaceAntiSpoofingAdvanced.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/ImageFormatEncoder$ImageFormat.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/ImageFormatEncoder.class +0 -0
- package/android/src/main/java/com/faceantispoof/FaceAntiSpoofFrameProcessor.kt +1 -0
- package/android/src/main/java/com/faceantispoof/FaceAntiSpoofingAdvanced.kt +5 -4
- package/android/src/main/java/com/faceantispoof/ImageFormatEncoder.kt +151 -46
- package/package.json +3 -3
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/arm64-v8a/generate_cxx_metadata_2688_timing.txt +0 -9
- package/android/build/intermediates/cxx/Debug/2a1it684/logs/x86_64/generate_cxx_metadata_2687_timing.txt +0 -9
- /package/android/.cxx/Debug/2a1it684/x86/.cmake/api/v1/reply/{index-2025-11-18T18-10-04-0841.json → index-2025-11-25T14-14-37-0548.json} +0 -0
- /package/android/.cxx/Debug/2a1it684/x86_64/.cmake/api/v1/reply/{index-2025-11-24T17-42-56-0679.json → index-2025-11-25T14-49-17-0490.json} +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len
CHANGED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/FaceAntiSpoofFrameProcessor.class
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/tmp/kotlin-classes/debug/com/faceantispoof/FaceAntiSpoofingAdvanced.class
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -153,6 +153,7 @@ class FaceAntiSpoofFrameProcessor : FrameProcessorPlugin() {
|
|
|
153
153
|
"combinedScore" to result.combinedScore.toDouble(),
|
|
154
154
|
"recognitionImageBase64" to result.recognitionImageBase64,
|
|
155
155
|
// Image format metadata
|
|
156
|
+
// NOTE: Image is in BGR format (OpenCV compatible), encoded as Base64 JPEG
|
|
156
157
|
"imageFormat" to result.imageFormat,
|
|
157
158
|
"imageResolution" to result.imageResolution,
|
|
158
159
|
"imageQuality" to result.imageQuality
|
|
@@ -412,6 +412,7 @@ class FaceAntiSpoofingAdvanced(private val assetManager: AssetManager) {
|
|
|
412
412
|
Log.d(TAG, "YUV to RGB conversion completed in ${convertTime}ms. RGB data: ${convertedRgb.size} bytes")
|
|
413
413
|
|
|
414
414
|
// Encode RGB to target format (JPEG, PNG, or BMP) and Base64
|
|
415
|
+
// NOTE: ImageFormatEncoder.rgbToBase64() automatically converts RGB→BGR for OpenCV compatibility
|
|
415
416
|
val startEncode = System.currentTimeMillis()
|
|
416
417
|
val format = when (outputImageFormat) {
|
|
417
418
|
"PNG" -> ImageFormatEncoder.ImageFormat.PNG
|
|
@@ -430,16 +431,16 @@ class FaceAntiSpoofingAdvanced(private val assetManager: AssetManager) {
|
|
|
430
431
|
|
|
431
432
|
if (base64Result != null) {
|
|
432
433
|
Log.d(TAG, "$outputImageFormat encoding completed in ${encodeTime}ms. Base64 size: ${base64Result.length} bytes")
|
|
433
|
-
Log.d(TAG, "✅ Generated ${outputImageResolution}×${outputImageResolution} $outputImageFormat Base64 for recognition API (total: ${convertTime + encodeTime}ms)")
|
|
434
|
+
Log.d(TAG, "✅ Generated ${outputImageResolution}×${outputImageResolution} $outputImageFormat Base64 for recognition API in BGR format (total: ${convertTime + encodeTime}ms)")
|
|
434
435
|
val estSize = estimateImageSize()
|
|
435
|
-
Log.d(TAG, "Format: $outputImageFormat, Quality: $outputImageQuality, Estimated: ${estSize / 1024}KB")
|
|
436
|
+
Log.d(TAG, "Format: $outputImageFormat (BGR), Quality: $outputImageQuality, Estimated: ${estSize / 1024}KB")
|
|
436
437
|
} else {
|
|
437
|
-
Log.w(TAG, "⚠️ ImageFormatEncoder returned null")
|
|
438
|
+
Log.w(TAG, "⚠️ ImageFormatEncoder returned null for BGR conversion")
|
|
438
439
|
}
|
|
439
440
|
|
|
440
441
|
base64Result
|
|
441
442
|
} catch (e: Exception) {
|
|
442
|
-
Log.e(TAG, "❌ Error generating ${outputImageResolution}×${outputImageResolution} $outputImageFormat Base64: ${e.message}", e)
|
|
443
|
+
Log.e(TAG, "❌ Error generating ${outputImageResolution}×${outputImageResolution} $outputImageFormat Base64 (BGR format): ${e.message}", e)
|
|
443
444
|
e.printStackTrace()
|
|
444
445
|
null
|
|
445
446
|
}
|
|
@@ -8,9 +8,11 @@ import java.io.ByteArrayOutputStream
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Multi-format image encoder supporting JPEG, PNG, and BMP.
|
|
11
|
-
* Handles
|
|
11
|
+
* Handles BGR data conversion (OpenCV compatible) to various image formats for compatibility
|
|
12
12
|
* with face recognition systems (OpenCV cv2.imdecode compatible).
|
|
13
13
|
*
|
|
14
|
+
* NOTE: Converts RGB input to BGR format as required by OpenCV and FastAPI server
|
|
15
|
+
*
|
|
14
16
|
* Supported formats:
|
|
15
17
|
* - JPEG: Compressed, good for network transmission (~80-100 KB at quality 85)
|
|
16
18
|
* - PNG: Lossless, larger file size (~200-300 KB)
|
|
@@ -36,15 +38,17 @@ object ImageFormatEncoder {
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
|
-
* Convert RGB data to
|
|
40
|
-
*
|
|
41
|
+
* Convert RGB data to BGR format (OpenCV compatible) and encode to specified image format.
|
|
42
|
+
* Returns Base64 string compatible with FastAPI server.
|
|
43
|
+
*
|
|
44
|
+
* IMPORTANT: This method performs RGB→BGR conversion required by OpenCV cv2.imdecode()
|
|
41
45
|
*
|
|
42
46
|
* @param rgbData RGB data as byte array (format: RGBRGBRGB..., 3 channels)
|
|
43
47
|
* @param width Image width (pixels)
|
|
44
48
|
* @param height Image height (pixels)
|
|
45
49
|
* @param format Target image format (JPEG, PNG, BMP)
|
|
46
50
|
* @param quality Compression quality for JPEG (0-100), ignored for PNG/BMP
|
|
47
|
-
* @return Base64 encoded image string, or null if encoding fails
|
|
51
|
+
* @return Base64 encoded image string in BGR color space, or null if encoding fails
|
|
48
52
|
*/
|
|
49
53
|
fun rgbToBase64(
|
|
50
54
|
rgbData: ByteArray,
|
|
@@ -57,18 +61,22 @@ object ImageFormatEncoder {
|
|
|
57
61
|
validateImageDimensions(width, height)
|
|
58
62
|
validateRgbData(rgbData, width, height)
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
// CRITICAL: Convert RGB to BGR for OpenCV compatibility
|
|
65
|
+
val bgrData = rgbToBgr(rgbData)
|
|
66
|
+
|
|
67
|
+
val imageBytes = bgrToImageBytes(bgrData, width, height, format, quality)
|
|
61
68
|
?: return null
|
|
62
69
|
|
|
63
70
|
Base64.encodeToString(imageBytes, Base64.NO_WRAP)
|
|
64
71
|
} catch (e: Exception) {
|
|
65
|
-
Log.e(TAG, "Failed to convert RGB to ${format.name} Base64: ${e.message}", e)
|
|
72
|
+
Log.e(TAG, "Failed to convert RGB to BGR ${format.name} Base64: ${e.message}", e)
|
|
66
73
|
null
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
/**
|
|
71
78
|
* Convert RGB float array (normalized 0-1) to image format and return as Base64.
|
|
79
|
+
* Performs RGB→BGR conversion for OpenCV compatibility.
|
|
72
80
|
* Each pixel is stored as 3 floats (R, G, B).
|
|
73
81
|
*
|
|
74
82
|
* @param rgbFloats RGB data as float array (normalized to 0-1)
|
|
@@ -76,7 +84,7 @@ object ImageFormatEncoder {
|
|
|
76
84
|
* @param height Image height
|
|
77
85
|
* @param format Target image format
|
|
78
86
|
* @param quality Compression quality for JPEG
|
|
79
|
-
* @return Base64 encoded image string
|
|
87
|
+
* @return Base64 encoded image string in BGR format
|
|
80
88
|
*/
|
|
81
89
|
fun rgbFloatToBase64(
|
|
82
90
|
rgbFloats: FloatArray,
|
|
@@ -113,20 +121,21 @@ object ImageFormatEncoder {
|
|
|
113
121
|
|
|
114
122
|
rgbToBase64(rgbBytes, width, height, format, quality)
|
|
115
123
|
} catch (e: Exception) {
|
|
116
|
-
Log.e(TAG, "Failed to convert RGB float to ${format.name} Base64: ${e.message}", e)
|
|
124
|
+
Log.e(TAG, "Failed to convert RGB float to BGR ${format.name} Base64: ${e.message}", e)
|
|
117
125
|
null
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
/**
|
|
122
130
|
* Convert RGB data to raw image bytes (not Base64).
|
|
131
|
+
* Performs RGB→BGR conversion for OpenCV compatibility.
|
|
123
132
|
*
|
|
124
133
|
* @param rgbData RGB data as byte array
|
|
125
134
|
* @param width Image width
|
|
126
135
|
* @param height Image height
|
|
127
136
|
* @param format Target image format
|
|
128
137
|
* @param quality Compression quality for JPEG
|
|
129
|
-
* @return Raw image bytes, or null if encoding fails
|
|
138
|
+
* @return Raw image bytes in BGR format, or null if encoding fails
|
|
130
139
|
*/
|
|
131
140
|
fun rgbToImageBytes(
|
|
132
141
|
rgbData: ByteArray,
|
|
@@ -139,29 +148,12 @@ object ImageFormatEncoder {
|
|
|
139
148
|
validateImageDimensions(width, height)
|
|
140
149
|
validateRgbData(rgbData, width, height)
|
|
141
150
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
when (format) {
|
|
147
|
-
ImageFormat.JPEG -> compressBitmapToBytes(bitmap, format, quality)
|
|
148
|
-
ImageFormat.PNG -> compressBitmapToBytes(bitmap, format, 100)
|
|
149
|
-
ImageFormat.BMP -> compressBitmapToBytes(bitmap, format, 100)
|
|
150
|
-
}
|
|
151
|
-
} catch (e: Exception) {
|
|
152
|
-
Log.e(TAG, "Error compressing bitmap: ${e.message}", e)
|
|
153
|
-
null
|
|
154
|
-
} finally {
|
|
155
|
-
try {
|
|
156
|
-
bitmap.recycle()
|
|
157
|
-
} catch (e: Exception) {
|
|
158
|
-
Log.w(TAG, "Error recycling bitmap: ${e.message}")
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
imageBytes
|
|
151
|
+
// CRITICAL: Convert RGB to BGR for OpenCV compatibility
|
|
152
|
+
val bgrData = rgbToBgr(rgbData)
|
|
153
|
+
|
|
154
|
+
bgrToImageBytes(bgrData, width, height, format, quality)
|
|
163
155
|
} catch (e: Exception) {
|
|
164
|
-
Log.e(TAG, "Failed to convert RGB to ${format.name} bytes: ${e.message}", e)
|
|
156
|
+
Log.e(TAG, "Failed to convert RGB to BGR ${format.name} bytes: ${e.message}", e)
|
|
165
157
|
null
|
|
166
158
|
}
|
|
167
159
|
}
|
|
@@ -226,13 +218,93 @@ object ImageFormatEncoder {
|
|
|
226
218
|
// ============ Private Helper Methods ============
|
|
227
219
|
|
|
228
220
|
/**
|
|
229
|
-
*
|
|
230
|
-
*
|
|
221
|
+
* Convert RGB byte array to BGR for OpenCV compatibility.
|
|
222
|
+
* CRITICAL: OpenCV expects BGR format, not RGB.
|
|
223
|
+
*
|
|
224
|
+
* @param rgbData RGB data in format RGBRGBRGB...
|
|
225
|
+
* @return BGR data in format BGRBGRBGR...
|
|
231
226
|
*/
|
|
232
|
-
private fun
|
|
227
|
+
private fun rgbToBgr(rgbData: ByteArray): ByteArray {
|
|
228
|
+
val bgrData = ByteArray(rgbData.size)
|
|
229
|
+
var rgbIdx = 0
|
|
230
|
+
var bgrIdx = 0
|
|
231
|
+
|
|
232
|
+
while (rgbIdx < rgbData.size && rgbIdx + 2 < rgbData.size) {
|
|
233
|
+
val r = rgbData[rgbIdx++]
|
|
234
|
+
val g = rgbData[rgbIdx++]
|
|
235
|
+
val b = rgbData[rgbIdx++]
|
|
236
|
+
|
|
237
|
+
// Swap: BGR order
|
|
238
|
+
bgrData[bgrIdx++] = b
|
|
239
|
+
bgrData[bgrIdx++] = g
|
|
240
|
+
bgrData[bgrIdx++] = r
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
Log.d(TAG, "Converted RGB to BGR: ${rgbData.size} bytes")
|
|
244
|
+
return bgrData
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Convert BGR data to raw image bytes (not Base64).
|
|
249
|
+
* BGR data is already in OpenCV format.
|
|
250
|
+
*
|
|
251
|
+
* @param bgrData BGR data as byte array (already in OpenCV format)
|
|
252
|
+
* @param width Image width
|
|
253
|
+
* @param height Image height
|
|
254
|
+
* @param format Target image format
|
|
255
|
+
* @param quality Compression quality for JPEG
|
|
256
|
+
* @return Raw image bytes, or null if encoding fails
|
|
257
|
+
*/
|
|
258
|
+
private fun bgrToImageBytes(
|
|
259
|
+
bgrData: ByteArray,
|
|
260
|
+
width: Int,
|
|
261
|
+
height: Int,
|
|
262
|
+
format: ImageFormat = ImageFormat.JPEG,
|
|
263
|
+
quality: Int = 85
|
|
264
|
+
): ByteArray? {
|
|
233
265
|
return try {
|
|
234
|
-
|
|
235
|
-
|
|
266
|
+
validateImageDimensions(width, height)
|
|
267
|
+
|
|
268
|
+
if (bgrData.size < width * height * 3) {
|
|
269
|
+
Log.e(TAG, "BGR data too small: expected ${width * height * 3}, got ${bgrData.size}")
|
|
270
|
+
return null
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
val bitmap = createBitmapFromBgr(bgrData, width, height)
|
|
274
|
+
?: return null
|
|
275
|
+
|
|
276
|
+
val imageBytes = try {
|
|
277
|
+
when (format) {
|
|
278
|
+
ImageFormat.JPEG -> compressBitmapToBytes(bitmap, format, quality)
|
|
279
|
+
ImageFormat.PNG -> compressBitmapToBytes(bitmap, format, 100)
|
|
280
|
+
ImageFormat.BMP -> compressBitmapToBytes(bitmap, format, 100)
|
|
281
|
+
}
|
|
282
|
+
} catch (e: Exception) {
|
|
283
|
+
Log.e(TAG, "Error compressing bitmap: ${e.message}", e)
|
|
284
|
+
null
|
|
285
|
+
} finally {
|
|
286
|
+
try {
|
|
287
|
+
bitmap.recycle()
|
|
288
|
+
} catch (e: Exception) {
|
|
289
|
+
Log.w(TAG, "Error recycling bitmap: ${e.message}")
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
imageBytes
|
|
294
|
+
} catch (e: Exception) {
|
|
295
|
+
Log.e(TAG, "Failed to convert BGR to ${format.name} bytes: ${e.message}", e)
|
|
296
|
+
null
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Create Bitmap from BGR byte array (OpenCV format).
|
|
302
|
+
* BGR format: BGRBGRBGR... (3 bytes per pixel, no alpha)
|
|
303
|
+
*/
|
|
304
|
+
private fun createBitmapFromBgr(bgrData: ByteArray, width: Int, height: Int): Bitmap? {
|
|
305
|
+
return try {
|
|
306
|
+
if (bgrData.isEmpty()) {
|
|
307
|
+
Log.e(TAG, "BGR data is empty")
|
|
236
308
|
return null
|
|
237
309
|
}
|
|
238
310
|
if (width <= 0 || height <= 0) {
|
|
@@ -241,31 +313,64 @@ object ImageFormatEncoder {
|
|
|
241
313
|
}
|
|
242
314
|
|
|
243
315
|
val expectedSize = width * height * 3
|
|
244
|
-
if (
|
|
245
|
-
Log.e(TAG, "
|
|
316
|
+
if (bgrData.size < expectedSize) {
|
|
317
|
+
Log.e(TAG, "BGR data too small: expected at least $expectedSize, got ${bgrData.size}")
|
|
246
318
|
return null
|
|
247
319
|
}
|
|
248
320
|
|
|
249
|
-
// Convert
|
|
321
|
+
// Convert BGR to ARGB for Bitmap (Android uses ARGB_8888)
|
|
322
|
+
// BGR order: B, G, R
|
|
250
323
|
val pixels = IntArray(width * height)
|
|
251
|
-
var
|
|
324
|
+
var bgrIdx = 0
|
|
252
325
|
for (i in pixels.indices) {
|
|
253
|
-
if (
|
|
254
|
-
Log.e(TAG, "
|
|
326
|
+
if (bgrIdx + 2 >= bgrData.size) {
|
|
327
|
+
Log.e(TAG, "BGR buffer index out of bounds at pixel $i")
|
|
255
328
|
return null
|
|
256
329
|
}
|
|
257
|
-
val
|
|
258
|
-
val g =
|
|
259
|
-
val
|
|
330
|
+
val b = bgrData[bgrIdx++].toInt() and 0xFF
|
|
331
|
+
val g = bgrData[bgrIdx++].toInt() and 0xFF
|
|
332
|
+
val r = bgrData[bgrIdx++].toInt() and 0xFF
|
|
260
333
|
pixels[i] = 0xFF000000.toInt() or (r shl 16) or (g shl 8) or b // ARGB
|
|
261
334
|
}
|
|
262
335
|
|
|
263
336
|
val bitmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888)
|
|
264
337
|
if (bitmap == null) {
|
|
265
|
-
Log.e(TAG, "Failed to create bitmap")
|
|
338
|
+
Log.e(TAG, "Failed to create bitmap from BGR")
|
|
266
339
|
return null
|
|
267
340
|
}
|
|
268
341
|
bitmap
|
|
342
|
+
} catch (e: Exception) {
|
|
343
|
+
Log.e(TAG, "Error creating bitmap from BGR: ${e.message}", e)
|
|
344
|
+
null
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Create Bitmap from RGB byte array.
|
|
350
|
+
* RGB format: RGBRGBRGB... (3 bytes per pixel, no alpha)
|
|
351
|
+
* DEPRECATED: Use createBitmapFromBgr instead for OpenCV compatibility
|
|
352
|
+
*/
|
|
353
|
+
@Deprecated("Use createBitmapFromBgr for OpenCV compatibility")
|
|
354
|
+
private fun createBitmapFromRgb(rgbData: ByteArray, width: Int, height: Int): Bitmap? {
|
|
355
|
+
return try {
|
|
356
|
+
if (rgbData.isEmpty()) {
|
|
357
|
+
Log.e(TAG, "RGB data is empty")
|
|
358
|
+
return null
|
|
359
|
+
}
|
|
360
|
+
if (width <= 0 || height <= 0) {
|
|
361
|
+
Log.e(TAG, "Invalid dimensions: width=$width, height=$height")
|
|
362
|
+
return null
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
val expectedSize = width * height * 3
|
|
366
|
+
if (rgbData.size < expectedSize) {
|
|
367
|
+
Log.e(TAG, "RGB data too small: expected at least $expectedSize, got ${rgbData.size}")
|
|
368
|
+
return null
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Convert RGB to BGR first, then to ARGB for Bitmap
|
|
372
|
+
val bgrData = rgbToBgr(rgbData)
|
|
373
|
+
createBitmapFromBgr(bgrData, width, height)
|
|
269
374
|
} catch (e: Exception) {
|
|
270
375
|
Log.e(TAG, "Error creating bitmap from RGB: ${e.message}", e)
|
|
271
376
|
null
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-vision-camera-spoof-detector",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "High-performance face anti-spoofing and liveness detection module for React Native Vision Camera. Uses TensorFlow Lite with GPU acceleration and optimized YUV processing.",
|
|
5
5
|
"homepage": "https://github.com/jescon-tech/react-native-vision-camera-spoof-detector",
|
|
6
6
|
"repository": {
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"bugs": {
|
|
11
11
|
"url": "https://github.com/jescon-tech/react-native-vision-camera-spoof-detector/issues"
|
|
12
12
|
},
|
|
13
|
-
"license": "
|
|
13
|
+
"license": "JESCON TECHNOLOGIES PVT LTD",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "PRAFULDAS M M",
|
|
16
|
-
"company": "JESCON TECHNOLOGIES PVT LTD",
|
|
16
|
+
"company": "JESCON TECHNOLOGIES PVT LTD THRISSUR, KERALA, INDIA",
|
|
17
17
|
"email": "jescontechnologies@gmail.com"
|
|
18
18
|
},
|
|
19
19
|
"main": "index.js",
|
|
File without changes
|