react-native-vision-camera-spoof-detector 1.0.21 → 1.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.
Files changed (197) hide show
  1. package/.gitattributes +2 -0
  2. package/.gitignore +27 -0
  3. package/CHANGELOG.md +2 -2
  4. package/CONTRIBUTING.md +2 -2
  5. package/README.md +442 -443
  6. package/android/build.gradle +12 -4
  7. package/android/src/main/cpp/CMakeLists.txt +101 -94
  8. package/android/src/main/cpp/libyuv/.clang-format +6 -6
  9. package/android/src/main/cpp/libyuv/.gn +40 -40
  10. package/android/src/main/cpp/libyuv/.vpython3 +410 -410
  11. package/android/src/main/cpp/libyuv/AUTHORS +7 -7
  12. package/android/src/main/cpp/libyuv/Android.bp +202 -202
  13. package/android/src/main/cpp/libyuv/Android.mk +106 -106
  14. package/android/src/main/cpp/libyuv/BUILD.gn +490 -490
  15. package/android/src/main/cpp/libyuv/CM_linux_packages.cmake +70 -70
  16. package/android/src/main/cpp/libyuv/CMakeLists.txt +259 -252
  17. package/android/src/main/cpp/libyuv/DEPS +935 -935
  18. package/android/src/main/cpp/libyuv/DIR_METADATA +3 -3
  19. package/android/src/main/cpp/libyuv/LICENSE +29 -29
  20. package/android/src/main/cpp/libyuv/OWNERS +11 -11
  21. package/android/src/main/cpp/libyuv/PATENTS +23 -23
  22. package/android/src/main/cpp/libyuv/PRESUBMIT.py +65 -65
  23. package/android/src/main/cpp/libyuv/README.chromium +11 -11
  24. package/android/src/main/cpp/libyuv/README.md +19 -19
  25. package/android/src/main/cpp/libyuv/build_overrides/build.gni +60 -60
  26. package/android/src/main/cpp/libyuv/build_overrides/gtest.gni +19 -19
  27. package/android/src/main/cpp/libyuv/build_overrides/partition_alloc.gni +17 -17
  28. package/android/src/main/cpp/libyuv/codereview.settings +5 -5
  29. package/android/src/main/cpp/libyuv/docs/deprecated_builds.md +409 -409
  30. package/android/src/main/cpp/libyuv/docs/environment_variables.md +64 -64
  31. package/android/src/main/cpp/libyuv/docs/feature_detection.md +108 -108
  32. package/android/src/main/cpp/libyuv/docs/filtering.md +196 -196
  33. package/android/src/main/cpp/libyuv/docs/formats.md +208 -208
  34. package/android/src/main/cpp/libyuv/docs/getting_started.md +296 -296
  35. package/android/src/main/cpp/libyuv/docs/rotation.md +107 -107
  36. package/android/src/main/cpp/libyuv/download_vs_toolchain.py +29 -29
  37. package/android/src/main/cpp/libyuv/include/libyuv/basic_types.h +68 -68
  38. package/android/src/main/cpp/libyuv/include/libyuv/compare.h +111 -111
  39. package/android/src/main/cpp/libyuv/include/libyuv/compare_row.h +112 -112
  40. package/android/src/main/cpp/libyuv/include/libyuv/convert.h +1117 -1117
  41. package/android/src/main/cpp/libyuv/include/libyuv/convert_argb.h +2335 -2335
  42. package/android/src/main/cpp/libyuv/include/libyuv/convert_from.h +203 -203
  43. package/android/src/main/cpp/libyuv/include/libyuv/convert_from_argb.h +394 -394
  44. package/android/src/main/cpp/libyuv/include/libyuv/cpu_id.h +147 -147
  45. package/android/src/main/cpp/libyuv/include/libyuv/cpu_support.h +99 -99
  46. package/android/src/main/cpp/libyuv/include/libyuv/loongson_intrinsics.h +1949 -1949
  47. package/android/src/main/cpp/libyuv/include/libyuv/mjpeg_decoder.h +195 -195
  48. package/android/src/main/cpp/libyuv/include/libyuv/planar_functions.h +1131 -1131
  49. package/android/src/main/cpp/libyuv/include/libyuv/rotate.h +296 -296
  50. package/android/src/main/cpp/libyuv/include/libyuv/rotate_argb.h +37 -37
  51. package/android/src/main/cpp/libyuv/include/libyuv/rotate_row.h +265 -265
  52. package/android/src/main/cpp/libyuv/include/libyuv/row.h +6738 -6738
  53. package/android/src/main/cpp/libyuv/include/libyuv/row_sve.h +2154 -2154
  54. package/android/src/main/cpp/libyuv/include/libyuv/scale.h +336 -336
  55. package/android/src/main/cpp/libyuv/include/libyuv/scale_argb.h +76 -76
  56. package/android/src/main/cpp/libyuv/include/libyuv/scale_rgb.h +42 -42
  57. package/android/src/main/cpp/libyuv/include/libyuv/scale_row.h +1726 -1726
  58. package/android/src/main/cpp/libyuv/include/libyuv/scale_uv.h +51 -51
  59. package/android/src/main/cpp/libyuv/include/libyuv/version.h +16 -16
  60. package/android/src/main/cpp/libyuv/include/libyuv/video_common.h +222 -222
  61. package/android/src/main/cpp/libyuv/include/libyuv.h +33 -33
  62. package/android/src/main/cpp/libyuv/infra/config/OWNERS +3 -3
  63. package/android/src/main/cpp/libyuv/infra/config/PRESUBMIT.py +17 -17
  64. package/android/src/main/cpp/libyuv/infra/config/README.md +2 -2
  65. package/android/src/main/cpp/libyuv/infra/config/codereview.settings +6 -6
  66. package/android/src/main/cpp/libyuv/infra/config/commit-queue.cfg +144 -144
  67. package/android/src/main/cpp/libyuv/infra/config/cr-buildbucket.cfg +1185 -1185
  68. package/android/src/main/cpp/libyuv/infra/config/luci-logdog.cfg +9 -9
  69. package/android/src/main/cpp/libyuv/infra/config/luci-milo.cfg +246 -246
  70. package/android/src/main/cpp/libyuv/infra/config/luci-scheduler.cfg +385 -385
  71. package/android/src/main/cpp/libyuv/infra/config/main.star +402 -402
  72. package/android/src/main/cpp/libyuv/infra/config/project.cfg +16 -16
  73. package/android/src/main/cpp/libyuv/infra/config/realms.cfg +111 -111
  74. package/android/src/main/cpp/libyuv/libyuv.gni +34 -34
  75. package/android/src/main/cpp/libyuv/libyuv.gyp +149 -149
  76. package/android/src/main/cpp/libyuv/libyuv.gypi +87 -87
  77. package/android/src/main/cpp/libyuv/linux.mk +96 -96
  78. package/android/src/main/cpp/libyuv/public.mk +13 -13
  79. package/android/src/main/cpp/libyuv/pylintrc +49 -49
  80. package/android/src/main/cpp/libyuv/riscv_script/prepare_toolchain_qemu.sh +74 -74
  81. package/android/src/main/cpp/libyuv/riscv_script/riscv-clang.cmake +56 -56
  82. package/android/src/main/cpp/libyuv/riscv_script/run_qemu.sh +15 -15
  83. package/android/src/main/cpp/libyuv/source/compare.cc +435 -435
  84. package/android/src/main/cpp/libyuv/source/compare_common.cc +74 -74
  85. package/android/src/main/cpp/libyuv/source/compare_gcc.cc +362 -362
  86. package/android/src/main/cpp/libyuv/source/compare_neon.cc +96 -96
  87. package/android/src/main/cpp/libyuv/source/compare_neon64.cc +223 -223
  88. package/android/src/main/cpp/libyuv/source/compare_win.cc +241 -241
  89. package/android/src/main/cpp/libyuv/source/convert.cc +4746 -4746
  90. package/android/src/main/cpp/libyuv/source/convert_argb.cc +9179 -9179
  91. package/android/src/main/cpp/libyuv/source/convert_from.cc +866 -866
  92. package/android/src/main/cpp/libyuv/source/convert_from_argb.cc +3671 -3671
  93. package/android/src/main/cpp/libyuv/source/convert_jpeg.cc +602 -602
  94. package/android/src/main/cpp/libyuv/source/convert_to_argb.cc +391 -391
  95. package/android/src/main/cpp/libyuv/source/convert_to_i420.cc +288 -288
  96. package/android/src/main/cpp/libyuv/source/cpu_id.cc +496 -496
  97. package/android/src/main/cpp/libyuv/source/mjpeg_decoder.cc +580 -580
  98. package/android/src/main/cpp/libyuv/source/mjpeg_validate.cc +71 -71
  99. package/android/src/main/cpp/libyuv/source/planar_functions.cc +5663 -5663
  100. package/android/src/main/cpp/libyuv/source/rotate.cc +1241 -1241
  101. package/android/src/main/cpp/libyuv/source/rotate_any.cc +76 -76
  102. package/android/src/main/cpp/libyuv/source/rotate_argb.cc +259 -259
  103. package/android/src/main/cpp/libyuv/source/rotate_common.cc +208 -208
  104. package/android/src/main/cpp/libyuv/source/rotate_gcc.cc +505 -505
  105. package/android/src/main/cpp/libyuv/source/rotate_lsx.cc +233 -233
  106. package/android/src/main/cpp/libyuv/source/rotate_neon.cc +219 -219
  107. package/android/src/main/cpp/libyuv/source/rotate_neon64.cc +273 -273
  108. package/android/src/main/cpp/libyuv/source/rotate_sme.cc +174 -174
  109. package/android/src/main/cpp/libyuv/source/rotate_win.cc +253 -253
  110. package/android/src/main/cpp/libyuv/source/row_any.cc +2519 -2519
  111. package/android/src/main/cpp/libyuv/source/row_common.cc +4461 -4461
  112. package/android/src/main/cpp/libyuv/source/row_gcc.cc +9570 -9570
  113. package/android/src/main/cpp/libyuv/source/row_lasx.cc +2343 -2343
  114. package/android/src/main/cpp/libyuv/source/row_lsx.cc +3030 -3030
  115. package/android/src/main/cpp/libyuv/source/row_neon.cc +4026 -4026
  116. package/android/src/main/cpp/libyuv/source/row_neon64.cc +5617 -5617
  117. package/android/src/main/cpp/libyuv/source/row_rvv.cc +2599 -2599
  118. package/android/src/main/cpp/libyuv/source/row_sme.cc +1183 -1183
  119. package/android/src/main/cpp/libyuv/source/row_sve.cc +1088 -1088
  120. package/android/src/main/cpp/libyuv/source/row_win.cc +6453 -6453
  121. package/android/src/main/cpp/libyuv/source/scale.cc +2710 -2710
  122. package/android/src/main/cpp/libyuv/source/scale_any.cc +991 -991
  123. package/android/src/main/cpp/libyuv/source/scale_argb.cc +1158 -1158
  124. package/android/src/main/cpp/libyuv/source/scale_common.cc +1977 -1977
  125. package/android/src/main/cpp/libyuv/source/scale_gcc.cc +2947 -2947
  126. package/android/src/main/cpp/libyuv/source/scale_lsx.cc +739 -739
  127. package/android/src/main/cpp/libyuv/source/scale_neon.cc +1449 -1449
  128. package/android/src/main/cpp/libyuv/source/scale_neon64.cc +1552 -1552
  129. package/android/src/main/cpp/libyuv/source/scale_rgb.cc +82 -82
  130. package/android/src/main/cpp/libyuv/source/scale_rvv.cc +1971 -1971
  131. package/android/src/main/cpp/libyuv/source/scale_sme.cc +555 -555
  132. package/android/src/main/cpp/libyuv/source/scale_uv.cc +1159 -1159
  133. package/android/src/main/cpp/libyuv/source/scale_win.cc +1392 -1392
  134. package/android/src/main/cpp/libyuv/source/test.sh +35 -35
  135. package/android/src/main/cpp/libyuv/source/video_common.cc +62 -62
  136. package/android/src/main/cpp/libyuv/tools_libyuv/OWNERS +4 -4
  137. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/roll_deps.py +931 -931
  138. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/roll_deps_test.py +164 -164
  139. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS +21 -21
  140. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.new +13 -13
  141. package/android/src/main/cpp/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.old +13 -13
  142. package/android/src/main/cpp/libyuv/tools_libyuv/get_landmines.py +38 -38
  143. package/android/src/main/cpp/libyuv/tools_libyuv/msan/OWNERS +3 -3
  144. package/android/src/main/cpp/libyuv/tools_libyuv/msan/blacklist.txt +9 -9
  145. package/android/src/main/cpp/libyuv/tools_libyuv/ubsan/OWNERS +3 -3
  146. package/android/src/main/cpp/libyuv/tools_libyuv/ubsan/blacklist.txt +15 -15
  147. package/android/src/main/cpp/libyuv/tools_libyuv/ubsan/vptr_blacklist.txt +25 -25
  148. package/android/src/main/cpp/libyuv/unit_test/basictypes_test.cc +43 -43
  149. package/android/src/main/cpp/libyuv/unit_test/color_test.cc +848 -848
  150. package/android/src/main/cpp/libyuv/unit_test/compare_test.cc +739 -739
  151. package/android/src/main/cpp/libyuv/unit_test/convert_argb_test.cc +2867 -2867
  152. package/android/src/main/cpp/libyuv/unit_test/convert_test.cc +2133 -2133
  153. package/android/src/main/cpp/libyuv/unit_test/cpu_test.cc +427 -427
  154. package/android/src/main/cpp/libyuv/unit_test/cpu_thread_test.cc +63 -63
  155. package/android/src/main/cpp/libyuv/unit_test/math_test.cc +160 -160
  156. package/android/src/main/cpp/libyuv/unit_test/planar_test.cc +4731 -4731
  157. package/android/src/main/cpp/libyuv/unit_test/rotate_argb_test.cc +334 -334
  158. package/android/src/main/cpp/libyuv/unit_test/rotate_test.cc +962 -962
  159. package/android/src/main/cpp/libyuv/unit_test/scale_argb_test.cc +590 -590
  160. package/android/src/main/cpp/libyuv/unit_test/scale_plane_test.cc +465 -465
  161. package/android/src/main/cpp/libyuv/unit_test/scale_rgb_test.cc +280 -280
  162. package/android/src/main/cpp/libyuv/unit_test/scale_test.cc +1135 -1135
  163. package/android/src/main/cpp/libyuv/unit_test/scale_uv_test.cc +249 -249
  164. package/android/src/main/cpp/libyuv/unit_test/testdata/arm_v7.txt +12 -12
  165. package/android/src/main/cpp/libyuv/unit_test/testdata/mips.txt +7 -7
  166. package/android/src/main/cpp/libyuv/unit_test/testdata/mips_loongson2k.txt +5 -5
  167. package/android/src/main/cpp/libyuv/unit_test/testdata/mips_loongson3.txt +10 -10
  168. package/android/src/main/cpp/libyuv/unit_test/testdata/mips_loongson_mmi.txt +7 -7
  169. package/android/src/main/cpp/libyuv/unit_test/testdata/riscv64.txt +3 -3
  170. package/android/src/main/cpp/libyuv/unit_test/testdata/riscv64_rvv.txt +3 -3
  171. package/android/src/main/cpp/libyuv/unit_test/testdata/riscv64_rvv_zvfh.txt +3 -3
  172. package/android/src/main/cpp/libyuv/unit_test/testdata/tegra3.txt +23 -23
  173. package/android/src/main/cpp/libyuv/unit_test/unit_test.cc +581 -581
  174. package/android/src/main/cpp/libyuv/unit_test/unit_test.h +232 -232
  175. package/android/src/main/cpp/libyuv/unit_test/video_common_test.cc +112 -112
  176. package/android/src/main/cpp/libyuv/util/Makefile +9 -9
  177. package/android/src/main/cpp/libyuv/util/color.cc +120 -120
  178. package/android/src/main/cpp/libyuv/util/compare.cc +67 -67
  179. package/android/src/main/cpp/libyuv/util/cpuid.c +211 -211
  180. package/android/src/main/cpp/libyuv/util/i444tonv12_eg.cc +27 -27
  181. package/android/src/main/cpp/libyuv/util/psnr.cc +291 -291
  182. package/android/src/main/cpp/libyuv/util/psnr.h +47 -47
  183. package/android/src/main/cpp/libyuv/util/psnr_main.cc +620 -620
  184. package/android/src/main/cpp/libyuv/util/ssim.cc +364 -364
  185. package/android/src/main/cpp/libyuv/util/ssim.h +38 -38
  186. package/android/src/main/cpp/libyuv/util/yuvconstants.c +114 -114
  187. package/android/src/main/cpp/libyuv/util/yuvconvert.cc +367 -367
  188. package/android/src/main/cpp/libyuv/winarm.mk +47 -47
  189. package/package.json +86 -84
  190. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  191. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  192. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  193. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  194. package/android/.gradle/8.9/gc.properties +0 -0
  195. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  196. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  197. package/android/.gradle/vcs-1/gc.properties +0 -0
package/README.md CHANGED
@@ -1,443 +1,442 @@
1
- # react-native-vision-camera-spoof-detector
2
-
3
- [![npm version](https://badge.fury.io/js/react-native-vision-camera-spoof-detector.svg)](https://badge.fury.io/js/react-native-vision-camera-spoof-detector)
4
- [![License: JESCON TECHNOLOGIES PVT LTD](https://img.shields.io/badge/License-JESCON TECHNOLOGIES PVT LTD-yellow.svg)](https://opensource.org/licenses/JESCON TECHNOLOGIES PVT LTD)
5
- [![GitHub](https://img.shields.io/badge/GitHub-Repository-blue)](https://github.com/jescon-tech/react-native-vision-camera-spoof-detector)
6
-
7
- High-performance face anti-spoofing and liveness detection module for React Native Vision Camera. Features TensorFlow Lite with GPU acceleration, optimized YUV processing, and real-time blink detection for robust liveness verification.
8
-
9
- ## 🎯 Features
10
-
11
- - **🚀 Real-time Performance**: GPU-accelerated TensorFlow Lite processing for smooth 60fps detection
12
- - **🎯 High Accuracy**: Advanced ML models for distinguishing live faces from spoofing attempts
13
- - **👁️ Blink Detection**: Native blink detection for enhanced liveness verification
14
- - **📱 Optimized YUV Processing**: Efficient image data handling for React Native
15
- - **🔧 Easy Integration**: Seamlessly integrates with `react-native-vision-camera`
16
- - **⚡ Face Stability Tracking**: Automatic stable face detection with customizable thresholds
17
- - **🛡️ Face Centering**: Intelligent face positioning validation in frame
18
- - **📊 Anti-spoofing Confidence**: Detailed confidence scores with multiple detection models
19
- - **🔄 Batched Updates**: Optimized state management with minimal re-renders
20
-
21
- ## 📋 Requirements
22
-
23
- - React Native >= 0.60.0
24
- - react-native-vision-camera >= 4.6.4
25
- - react-native-reanimated >= 3.0.0
26
- - react-native-worklets-core >= 1.0.0
27
- - react-native-vision-camera-face-detector (optional, for enhanced features)
28
-
29
- ## 📦 Installation
30
-
31
- ### Step 1: Install the package
32
-
33
- ```bash
34
- npm install react-native-vision-camera-spoof-detector
35
- # or
36
- yarn add react-native-vision-camera-spoof-detector
37
- ```
38
-
39
- ### Step 2: Install peer dependencies
40
-
41
- ```bash
42
- npm install react-native-vision-camera react-native-reanimated react-native-worklets-core
43
- # or
44
- yarn add react-native-vision-camera react-native-reanimated react-native-worklets-core
45
- ```
46
-
47
- ### Step 3: Configure Android (if not auto-linked)
48
-
49
- Add to `android/app/build.gradle`:
50
-
51
- ```gradle
52
- dependencies {
53
- implementation project(':react-native-vision-camera-spoof-detector')
54
- }
55
- ```
56
-
57
- ### Step 4: Link native module (for React Native < 0.60)
58
-
59
- ```bash
60
- react-native link react-native-vision-camera-spoof-detector
61
- ```
62
-
63
- ## 🚀 Quick Start
64
-
65
- ### Simple Usage
66
-
67
- ```javascript
68
- import React, { useEffect, useState } from 'react';
69
- import { StyleSheet, Text, View } from 'react-native';
70
- import { Camera, useCameraDevices, useFrameProcessor } from 'react-native-vision-camera';
71
- import { faceAntiSpoofFrameProcessor, initializeFaceAntiSpoof } from 'react-native-vision-camera-spoof-detector';
72
- import { runOnJS } from 'react-native-reanimated';
73
-
74
- export default function App() {
75
- const devices = useCameraDevices();
76
- const device = devices.front;
77
- const [spoofResult, setSpoofResult] = useState(null);
78
-
79
- useEffect(() => {
80
- initializeFaceAntiSpoof().then((success) => {
81
- console.log('FaceAntiSpoof initialized:', success);
82
- });
83
- }, []);
84
-
85
- const frameProcessor = useFrameProcessor((frame) => {
86
- 'worklet';
87
- const result = faceAntiSpoofFrameProcessor(frame);
88
- if (result) {
89
- runOnJS(setSpoofResult)(result);
90
- }
91
- }, []);
92
-
93
- if (device == null) return <Text>Loading...</Text>;
94
-
95
- return (
96
- <View style={styles.container}>
97
- <Camera
98
- style={StyleSheet.absoluteFill}
99
- device={device}
100
- isActive={true}
101
- frameProcessor={frameProcessor}
102
- frameProcessorFps={5}
103
- />
104
- {spoofResult && (
105
- <View style={styles.resultContainer}>
106
- <Text style={styles.resultText}>
107
- Is Live: {spoofResult.isLive ? 'Yes' : 'No'}
108
- </Text>
109
- <Text style={styles.resultText}>
110
- Score: {spoofResult.neuralNetworkScore?.toFixed(2)}
111
- </Text>
112
- <Text style={styles.resultText}>
113
- Label: {spoofResult.label}
114
- </Text>
115
- </View>
116
- )}
117
- </View>
118
- );
119
- }
120
-
121
- const styles = StyleSheet.create({
122
- container: { flex: 1 },
123
- resultContainer: {
124
- position: 'absolute',
125
- bottom: 50,
126
- left: 0,
127
- right: 0,
128
- alignItems: 'center',
129
- backgroundColor: 'rgba(0,0,0,0.5)',
130
- padding: 10,
131
- },
132
- resultText: {
133
- color: 'white',
134
- fontSize: 20,
135
- fontWeight: 'bold',
136
- },
137
- });
138
- ```
139
-
140
- ### Advanced Usage with Full Feature Set
141
-
142
- ```javascript
143
- import { useCallback, useMemo, useEffect, useRef } from 'react';
144
- import { Worklets } from 'react-native-worklets-core';
145
- import { useFrameProcessor } from 'react-native-vision-camera';
146
- import { useFaceDetector } from 'react-native-vision-camera-face-detector';
147
- import {
148
- faceAntiSpoofFrameProcessor,
149
- initializeFaceAntiSpoof,
150
- isFaceAntiSpoofAvailable,
151
- } from 'react-native-vision-camera-spoof-detector';
152
-
153
- const useFaceDetectionFrameProcessor = ({
154
- onStableFaceDetected = () => { },
155
- onFacesUpdate = () => { },
156
- onLivenessUpdate = () => { },
157
- onAntiSpoofUpdate = () => { },
158
- showCodeScanner = false,
159
- isLoading = false,
160
- isActive = true,
161
- livenessLevel = 0,
162
- antispooflevel = 0.35,
163
- }) => {
164
- const { detectFaces } = useFaceDetector({
165
- performanceMode: 'fast',
166
- landmarkMode: 'none',
167
- contourMode: 'none',
168
- classificationMode: livenessLevel === 1 ? 'all' : 'none',
169
- minFaceSize: 0.2,
170
- });
171
-
172
- const isMounted = useRef(true);
173
- const antiSpoofInitialized = useRef(false);
174
-
175
- const initializeAntiSpoof = useCallback(async () => {
176
- if (antiSpoofInitialized.current) return true;
177
- try {
178
- const available = isFaceAntiSpoofAvailable?.();
179
- if (!available) return false;
180
- await initializeFaceAntiSpoof();
181
- antiSpoofInitialized.current = true;
182
- return true;
183
- } catch (err) {
184
- console.error('Anti-spoof initialization error:', err);
185
- return false;
186
- }
187
- }, []);
188
-
189
- useEffect(() => {
190
- initializeAntiSpoof();
191
- }, [initializeAntiSpoof]);
192
-
193
- // Shared state for face tracking
194
- const sharedState = useMemo(
195
- () =>
196
- Worklets.createSharedValue({
197
- flags: {
198
- captured: false,
199
- showCodeScanner: showCodeScanner,
200
- isActive: isActive,
201
- hasSingleFace: false,
202
- isFaceCentered: false,
203
- },
204
- antiSpoof: {
205
- isLive: false,
206
- confidence: 0,
207
- consecutiveLiveFrames: 0,
208
- },
209
- }),
210
- []
211
- );
212
-
213
- const frameProcessor = useFrameProcessor(
214
- (frame) => {
215
- 'worklet';
216
-
217
- try {
218
- const detected = detectFaces?.(frame);
219
-
220
- if (!detected || detected.length === 0) {
221
- onFacesUpdate?.({ count: 0, progress: 0 });
222
- return;
223
- }
224
-
225
- if (detected.length === 1 && !sharedState.value.flags.captured) {
226
- const antiSpoofResult = faceAntiSpoofFrameProcessor?.(frame);
227
-
228
- if (antiSpoofResult?.isLive) {
229
- sharedState.value.antiSpoof.isLive = true;
230
- sharedState.value.antiSpoof.confidence = antiSpoofResult.combinedScore;
231
- onAntiSpoofUpdate?.({
232
- isLive: true,
233
- confidence: antiSpoofResult.combinedScore,
234
- });
235
- }
236
-
237
- onFacesUpdate?.({ count: 1, progress: 50 });
238
- } else {
239
- onFacesUpdate?.({ count: detected.length, progress: 0 });
240
- }
241
- } catch (err) {
242
- console.error('Frame processing error:', err);
243
- } finally {
244
- frame.release?.();
245
- }
246
- },
247
- [detectFaces, isLoading]
248
- );
249
-
250
- return {
251
- frameProcessor,
252
- sharedState,
253
- initializeAntiSpoof,
254
- };
255
- };
256
-
257
- export default useFaceDetectionFrameProcessor;
258
- ```
259
-
260
- ## 📚 API Reference
261
-
262
- ### `initializeFaceAntiSpoof()`
263
-
264
- Initializes the face anti-spoofing module. Must be called before using the frame processor.
265
-
266
- ```javascript
267
- const success = await initializeFaceAntiSpoof();
268
- ```
269
-
270
- **Returns**: `Promise<boolean>` - True if successful
271
-
272
- ---
273
-
274
- ### `isFaceAntiSpoofAvailable()`
275
-
276
- Checks if the module is available on the device.
277
-
278
- ```javascript
279
- const available = isFaceAntiSpoofAvailable();
280
- ```
281
-
282
- **Returns**: `boolean`
283
-
284
- ---
285
-
286
- ### `faceAntiSpoofFrameProcessor(frame)`
287
-
288
- Process frame and get anti-spoofing result.
289
-
290
- ```javascript
291
- const result = faceAntiSpoofFrameProcessor(frame);
292
- ```
293
-
294
- **Parameters**: `frame` (Vision Camera Frame)
295
-
296
- **Returns**: `FaceAntiSpoofingResult | null`
297
-
298
- ### `FaceAntiSpoofingResult`
299
-
300
- ```typescript
301
- interface FaceAntiSpoofingResult {
302
- isLive: boolean; // Real face (true) or spoof (false)
303
- label: string; // "Live Face" or "Spoof Face"
304
- neuralNetworkScore: number; // 0.0-1.0 confidence
305
- laplacianScore: number; // Image quality score
306
- combinedScore: number; // Weighted average
307
- error?: string; // Error message if any
308
- }
309
- ```
310
-
311
- ## 🔧 Configuration
312
-
313
- ```javascript
314
- // Anti-spoofing sensitivity (0.0-1.0, lower = more lenient)
315
- const antispooflevel = 0.35;
316
-
317
- // Liveness verification mode
318
- // 0: Anti-spoofing only
319
- // 1: Anti-spoofing + blink detection
320
- const livenessLevel = 1;
321
-
322
- // Customizable thresholds
323
- const FACE_STABILITY_THRESHOLD = 3; // Frames for stable face
324
- const FACE_MOVEMENT_THRESHOLD = 15; // Max pixel movement
325
- const BLINK_THRESHOLD = 0.3; // Eye closure probability
326
- const REQUIRED_BLINKS = 3; // Blinks for liveness
327
- const REQUIRED_CONSECUTIVE_LIVE_FRAMES = 3; // Consecutive live frames
328
- const REAL_LAPLACIAN_THRESHOLD = 3500; // Image quality threshold
329
- const FACE_CENTER_THRESHOLD_X = 0.2; // X-axis tolerance
330
- const FACE_CENTER_THRESHOLD_Y = 0.15; // Y-axis tolerance
331
- ```
332
-
333
- ## 🎮 Complete Examples
334
-
335
- Check the [examples](./examples) folder for:
336
- - Basic anti-spoofing detection
337
- - Face detection with liveness
338
- - Complete capture flow
339
- - UI components and feedback
340
-
341
- ## 🔍 Attack Detection Capabilities
342
-
343
- The module detects and prevents:
344
- - ✅ Print attacks (photos)
345
- - ✅ Display attacks (screens/tablets)
346
- - ✅ Mask attacks (with blink detection)
347
- - ✅ Replay attacks (videos)
348
-
349
- Performance depends on:
350
- - Image quality
351
- - Lighting conditions
352
- - Face angle and positioning
353
- - Device camera specs
354
-
355
- ## ⚙️ Performance Tips
356
-
357
- 1. Use `performanceMode: 'fast'` in Face Detector
358
- 2. Module automatically batches state updates
359
- 3. Adjust `FRAME_PROCESSOR_MIN_INTERVAL_MS` as needed
360
- 4. GPU acceleration is used automatically when available
361
- 5. Proper frame release prevents memory leaks
362
-
363
- ## 📱 Platform Support
364
-
365
- | Platform | Status | GPU | Notes |
366
- |----------|--------|-----|-------|
367
- | Android | Supported | Yes | Fully optimized |
368
- | iOS | In Progress | Yes | Coming soon |
369
- | Web | ❌ No | N/A | Not applicable |
370
-
371
- ## 🐛 Troubleshooting
372
-
373
- **Module won't initialize**
374
- ```javascript
375
- const available = isFaceAntiSpoofAvailable();
376
- if (!available) {
377
- console.log('Not available on this device');
378
- }
379
- ```
380
-
381
- **Low accuracy**
382
- - Check lighting conditions
383
- - Ensure face is centered
384
- - Adjust `antispooflevel` parameter
385
- - Verify TensorFlow Lite models are bundled
386
-
387
- **Performance issues**
388
- - Reduce frame processing frequency
389
- - Use lower camera resolution
390
- - Enable fast performance mode
391
- - Check device temperature
392
-
393
- **Face detection fails**
394
- - Ensure clear face visibility
395
- - Check camera permissions
396
- - Verify sufficient lighting
397
- - Check minimum face size threshold
398
-
399
- ## 📖 Documentation
400
-
401
- - [Complete API Documentation](./.docs/API.md)
402
- - [Migration Guide](./.docs/MIGRATION.md)
403
- - [Best Practices](./.docs/BEST_PRACTICES.md)
404
- - [Comprehensive Example](./examples/CompleteExampleApp.tsx)
405
-
406
- ## 🤝 Contributing
407
-
408
- Contributions welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
409
-
410
- ## 📄 License
411
-
412
- JESCON TECHNOLOGIES PVT LTD License - see [LICENSE](./LICENSE) file for details.
413
-
414
- ## 👨‍💼 Author
415
-
416
- **PRAFULDAS M M**
417
- - Company: JESCON TECHNOLOGIES PVT LTD
418
- - Location: Thrissur, Kerala, India
419
- - Email: jescontechnologies@gmail.com
420
-
421
- ## 🔗 Quick Links
422
-
423
- - [NPM Package](https://www.npmjs.com/package/react-native-vision-camera-spoof-detector)
424
- - [GitHub Repository](https://github.com/jescon-tech/react-native-vision-camera-spoof-detector)
425
- - [React Native Vision Camera](https://react-native-vision-camera.com)
426
- - [TensorFlow Lite](https://www.tensorflow.org/lite)
427
-
428
- ## 📞 Support & Community
429
-
430
- - 🐛 [Report Issues](https://github.com/jescon-tech/react-native-vision-camera-spoof-detector/issues)
431
- - 💬 [GitHub Discussions](https://github.com/jescon-tech/react-native-vision-camera-spoof-detector/discussions)
432
- - 📧 Email: jescontechnologies@gmail.com
433
-
434
- ## 🙏 Acknowledgments
435
-
436
- Built with:
437
- - [TensorFlow Lite](https://www.tensorflow.org/lite)
438
- - [React Native Vision Camera](https://react-native-vision-camera.com)
439
- - [React Native Worklets](https://docs.swmansion.com/react-native-worklets/)
440
-
441
- ---
442
-
443
- Made with ❤️ by JESCON TECHNOLOGIES PVT LTD
1
+ # react-native-vision-camera-spoof-detector
2
+
3
+ [![npm version](https://badge.fury.io/js/react-native-vision-camera-spoof-detector.svg)](https://badge.fury.io/js/react-native-vision-camera-spoof-detector)
4
+ [![GitHub](https://img.shields.io/badge/GitHub-Repository-blue)](https://github.com/dpraful/react-native-vision-camera-spoof-detector)
5
+
6
+ High-performance face anti-spoofing and liveness detection module for React Native Vision Camera. Features TensorFlow Lite with GPU acceleration, optimized YUV processing, and real-time blink detection for robust liveness verification.
7
+
8
+ ## 🎯 Features
9
+
10
+ - **🚀 Real-time Performance**: GPU-accelerated TensorFlow Lite processing for smooth 60fps detection
11
+ - **🎯 High Accuracy**: Advanced ML models for distinguishing live faces from spoofing attempts
12
+ - **👁️ Blink Detection**: Native blink detection for enhanced liveness verification
13
+ - **📱 Optimized YUV Processing**: Efficient image data handling for React Native
14
+ - **🔧 Easy Integration**: Seamlessly integrates with `react-native-vision-camera`
15
+ - **⚡ Face Stability Tracking**: Automatic stable face detection with customizable thresholds
16
+ - **🛡️ Face Centering**: Intelligent face positioning validation in frame
17
+ - **📊 Anti-spoofing Confidence**: Detailed confidence scores with multiple detection models
18
+ - **🔄 Batched Updates**: Optimized state management with minimal re-renders
19
+
20
+ ## 📋 Requirements
21
+
22
+ - React Native >= 0.60.0
23
+ - react-native-vision-camera >= 4.6.4
24
+ - react-native-reanimated >= 3.0.0
25
+ - react-native-worklets-core >= 1.0.0
26
+ - react-native-vision-camera-face-detector (optional, for enhanced features)
27
+
28
+ ## 📦 Installation
29
+
30
+ ### Step 1: Install the package
31
+
32
+ ```bash
33
+ npm install react-native-vision-camera-spoof-detector
34
+ # or
35
+ yarn add react-native-vision-camera-spoof-detector
36
+ ```
37
+
38
+ ### Step 2: Install peer dependencies
39
+
40
+ ```bash
41
+ npm install react-native-vision-camera react-native-reanimated react-native-worklets-core
42
+ # or
43
+ yarn add react-native-vision-camera react-native-reanimated react-native-worklets-core
44
+ ```
45
+
46
+ ### Step 3: Configure Android (if not auto-linked)
47
+
48
+ Add to `android/app/build.gradle`:
49
+
50
+ ```gradle
51
+ dependencies {
52
+ implementation project(':react-native-vision-camera-spoof-detector')
53
+ }
54
+ ```
55
+
56
+ ### Step 4: Link native module (for React Native < 0.60)
57
+
58
+ ```bash
59
+ react-native link react-native-vision-camera-spoof-detector
60
+ ```
61
+
62
+ ## 🚀 Quick Start
63
+
64
+ ### Simple Usage
65
+
66
+ ```javascript
67
+ import React, { useEffect, useState } from 'react';
68
+ import { StyleSheet, Text, View } from 'react-native';
69
+ import { Camera, useCameraDevices, useFrameProcessor } from 'react-native-vision-camera';
70
+ import { faceAntiSpoofFrameProcessor, initializeFaceAntiSpoof } from 'react-native-vision-camera-spoof-detector';
71
+ import { runOnJS } from 'react-native-reanimated';
72
+
73
+ export default function App() {
74
+ const devices = useCameraDevices();
75
+ const device = devices.front;
76
+ const [spoofResult, setSpoofResult] = useState(null);
77
+
78
+ useEffect(() => {
79
+ initializeFaceAntiSpoof().then((success) => {
80
+ console.log('FaceAntiSpoof initialized:', success);
81
+ });
82
+ }, []);
83
+
84
+ const frameProcessor = useFrameProcessor((frame) => {
85
+ 'worklet';
86
+ const result = faceAntiSpoofFrameProcessor(frame);
87
+ if (result) {
88
+ runOnJS(setSpoofResult)(result);
89
+ }
90
+ }, []);
91
+
92
+ if (device == null) return <Text>Loading...</Text>;
93
+
94
+ return (
95
+ <View style={styles.container}>
96
+ <Camera
97
+ style={StyleSheet.absoluteFill}
98
+ device={device}
99
+ isActive={true}
100
+ frameProcessor={frameProcessor}
101
+ frameProcessorFps={5}
102
+ />
103
+ {spoofResult && (
104
+ <View style={styles.resultContainer}>
105
+ <Text style={styles.resultText}>
106
+ Is Live: {spoofResult.isLive ? 'Yes' : 'No'}
107
+ </Text>
108
+ <Text style={styles.resultText}>
109
+ Score: {spoofResult.neuralNetworkScore?.toFixed(2)}
110
+ </Text>
111
+ <Text style={styles.resultText}>
112
+ Label: {spoofResult.label}
113
+ </Text>
114
+ </View>
115
+ )}
116
+ </View>
117
+ );
118
+ }
119
+
120
+ const styles = StyleSheet.create({
121
+ container: { flex: 1 },
122
+ resultContainer: {
123
+ position: 'absolute',
124
+ bottom: 50,
125
+ left: 0,
126
+ right: 0,
127
+ alignItems: 'center',
128
+ backgroundColor: 'rgba(0,0,0,0.5)',
129
+ padding: 10,
130
+ },
131
+ resultText: {
132
+ color: 'white',
133
+ fontSize: 20,
134
+ fontWeight: 'bold',
135
+ },
136
+ });
137
+ ```
138
+
139
+ ### Advanced Usage with Full Feature Set
140
+
141
+ ```javascript
142
+ import { useCallback, useMemo, useEffect, useRef } from 'react';
143
+ import { Worklets } from 'react-native-worklets-core';
144
+ import { useFrameProcessor } from 'react-native-vision-camera';
145
+ import { useFaceDetector } from 'react-native-vision-camera-face-detector';
146
+ import {
147
+ faceAntiSpoofFrameProcessor,
148
+ initializeFaceAntiSpoof,
149
+ isFaceAntiSpoofAvailable,
150
+ } from 'react-native-vision-camera-spoof-detector';
151
+
152
+ const useFaceDetectionFrameProcessor = ({
153
+ onStableFaceDetected = () => { },
154
+ onFacesUpdate = () => { },
155
+ onLivenessUpdate = () => { },
156
+ onAntiSpoofUpdate = () => { },
157
+ showCodeScanner = false,
158
+ isLoading = false,
159
+ isActive = true,
160
+ livenessLevel = 0,
161
+ antispooflevel = 0.35,
162
+ }) => {
163
+ const { detectFaces } = useFaceDetector({
164
+ performanceMode: 'fast',
165
+ landmarkMode: 'none',
166
+ contourMode: 'none',
167
+ classificationMode: livenessLevel === 1 ? 'all' : 'none',
168
+ minFaceSize: 0.2,
169
+ });
170
+
171
+ const isMounted = useRef(true);
172
+ const antiSpoofInitialized = useRef(false);
173
+
174
+ const initializeAntiSpoof = useCallback(async () => {
175
+ if (antiSpoofInitialized.current) return true;
176
+ try {
177
+ const available = isFaceAntiSpoofAvailable?.();
178
+ if (!available) return false;
179
+ await initializeFaceAntiSpoof();
180
+ antiSpoofInitialized.current = true;
181
+ return true;
182
+ } catch (err) {
183
+ console.error('Anti-spoof initialization error:', err);
184
+ return false;
185
+ }
186
+ }, []);
187
+
188
+ useEffect(() => {
189
+ initializeAntiSpoof();
190
+ }, [initializeAntiSpoof]);
191
+
192
+ // Shared state for face tracking
193
+ const sharedState = useMemo(
194
+ () =>
195
+ Worklets.createSharedValue({
196
+ flags: {
197
+ captured: false,
198
+ showCodeScanner: showCodeScanner,
199
+ isActive: isActive,
200
+ hasSingleFace: false,
201
+ isFaceCentered: false,
202
+ },
203
+ antiSpoof: {
204
+ isLive: false,
205
+ confidence: 0,
206
+ consecutiveLiveFrames: 0,
207
+ },
208
+ }),
209
+ []
210
+ );
211
+
212
+ const frameProcessor = useFrameProcessor(
213
+ (frame) => {
214
+ 'worklet';
215
+
216
+ try {
217
+ const detected = detectFaces?.(frame);
218
+
219
+ if (!detected || detected.length === 0) {
220
+ onFacesUpdate?.({ count: 0, progress: 0 });
221
+ return;
222
+ }
223
+
224
+ if (detected.length === 1 && !sharedState.value.flags.captured) {
225
+ const antiSpoofResult = faceAntiSpoofFrameProcessor?.(frame);
226
+
227
+ if (antiSpoofResult?.isLive) {
228
+ sharedState.value.antiSpoof.isLive = true;
229
+ sharedState.value.antiSpoof.confidence = antiSpoofResult.combinedScore;
230
+ onAntiSpoofUpdate?.({
231
+ isLive: true,
232
+ confidence: antiSpoofResult.combinedScore,
233
+ });
234
+ }
235
+
236
+ onFacesUpdate?.({ count: 1, progress: 50 });
237
+ } else {
238
+ onFacesUpdate?.({ count: detected.length, progress: 0 });
239
+ }
240
+ } catch (err) {
241
+ console.error('Frame processing error:', err);
242
+ } finally {
243
+ frame.release?.();
244
+ }
245
+ },
246
+ [detectFaces, isLoading]
247
+ );
248
+
249
+ return {
250
+ frameProcessor,
251
+ sharedState,
252
+ initializeAntiSpoof,
253
+ };
254
+ };
255
+
256
+ export default useFaceDetectionFrameProcessor;
257
+ ```
258
+
259
+ ## 📚 API Reference
260
+
261
+ ### `initializeFaceAntiSpoof()`
262
+
263
+ Initializes the face anti-spoofing module. Must be called before using the frame processor.
264
+
265
+ ```javascript
266
+ const success = await initializeFaceAntiSpoof();
267
+ ```
268
+
269
+ **Returns**: `Promise<boolean>` - True if successful
270
+
271
+ ---
272
+
273
+ ### `isFaceAntiSpoofAvailable()`
274
+
275
+ Checks if the module is available on the device.
276
+
277
+ ```javascript
278
+ const available = isFaceAntiSpoofAvailable();
279
+ ```
280
+
281
+ **Returns**: `boolean`
282
+
283
+ ---
284
+
285
+ ### `faceAntiSpoofFrameProcessor(frame)`
286
+
287
+ Process frame and get anti-spoofing result.
288
+
289
+ ```javascript
290
+ const result = faceAntiSpoofFrameProcessor(frame);
291
+ ```
292
+
293
+ **Parameters**: `frame` (Vision Camera Frame)
294
+
295
+ **Returns**: `FaceAntiSpoofingResult | null`
296
+
297
+ ### `FaceAntiSpoofingResult`
298
+
299
+ ```typescript
300
+ interface FaceAntiSpoofingResult {
301
+ isLive: boolean; // Real face (true) or spoof (false)
302
+ label: string; // "Live Face" or "Spoof Face"
303
+ neuralNetworkScore: number; // 0.0-1.0 confidence
304
+ laplacianScore: number; // Image quality score
305
+ combinedScore: number; // Weighted average
306
+ error?: string; // Error message if any
307
+ }
308
+ ```
309
+
310
+ ## 🔧 Configuration
311
+
312
+ ```javascript
313
+ // Anti-spoofing sensitivity (0.0-1.0, lower = more lenient)
314
+ const antispooflevel = 0.35;
315
+
316
+ // Liveness verification mode
317
+ // 0: Anti-spoofing only
318
+ // 1: Anti-spoofing + blink detection
319
+ const livenessLevel = 1;
320
+
321
+ // Customizable thresholds
322
+ const FACE_STABILITY_THRESHOLD = 3; // Frames for stable face
323
+ const FACE_MOVEMENT_THRESHOLD = 15; // Max pixel movement
324
+ const BLINK_THRESHOLD = 0.3; // Eye closure probability
325
+ const REQUIRED_BLINKS = 3; // Blinks for liveness
326
+ const REQUIRED_CONSECUTIVE_LIVE_FRAMES = 3; // Consecutive live frames
327
+ const REAL_LAPLACIAN_THRESHOLD = 3500; // Image quality threshold
328
+ const FACE_CENTER_THRESHOLD_X = 0.2; // X-axis tolerance
329
+ const FACE_CENTER_THRESHOLD_Y = 0.15; // Y-axis tolerance
330
+ ```
331
+
332
+ ## 🎮 Complete Examples
333
+
334
+ Check the [examples](./examples) folder for:
335
+ - Basic anti-spoofing detection
336
+ - Face detection with liveness
337
+ - Complete capture flow
338
+ - UI components and feedback
339
+
340
+ ## 🔍 Attack Detection Capabilities
341
+
342
+ The module detects and prevents:
343
+ - Print attacks (photos)
344
+ - ✅ Display attacks (screens/tablets)
345
+ - ✅ Mask attacks (with blink detection)
346
+ - ✅ Replay attacks (videos)
347
+
348
+ Performance depends on:
349
+ - Image quality
350
+ - Lighting conditions
351
+ - Face angle and positioning
352
+ - Device camera specs
353
+
354
+ ## ⚙️ Performance Tips
355
+
356
+ 1. Use `performanceMode: 'fast'` in Face Detector
357
+ 2. Module automatically batches state updates
358
+ 3. Adjust `FRAME_PROCESSOR_MIN_INTERVAL_MS` as needed
359
+ 4. GPU acceleration is used automatically when available
360
+ 5. Proper frame release prevents memory leaks
361
+
362
+ ## 📱 Platform Support
363
+
364
+ | Platform | Status | GPU | Notes |
365
+ |----------|--------|-----|-------|
366
+ | Android | ✅ Supported | Yes | Fully optimized |
367
+ | iOS | In Progress | Yes | Coming soon |
368
+ | Web | No | N/A | Not applicable |
369
+
370
+ ## 🐛 Troubleshooting
371
+
372
+ **Module won't initialize**
373
+ ```javascript
374
+ const available = isFaceAntiSpoofAvailable();
375
+ if (!available) {
376
+ console.log('Not available on this device');
377
+ }
378
+ ```
379
+
380
+ **Low accuracy**
381
+ - Check lighting conditions
382
+ - Ensure face is centered
383
+ - Adjust `antispooflevel` parameter
384
+ - Verify TensorFlow Lite models are bundled
385
+
386
+ **Performance issues**
387
+ - Reduce frame processing frequency
388
+ - Use lower camera resolution
389
+ - Enable fast performance mode
390
+ - Check device temperature
391
+
392
+ **Face detection fails**
393
+ - Ensure clear face visibility
394
+ - Check camera permissions
395
+ - Verify sufficient lighting
396
+ - Check minimum face size threshold
397
+
398
+ ## 📖 Documentation
399
+
400
+ - [Complete API Documentation](./.docs/API.md)
401
+ - [Migration Guide](./.docs/MIGRATION.md)
402
+ - [Best Practices](./.docs/BEST_PRACTICES.md)
403
+ - [Comprehensive Example](./examples/CompleteExampleApp.tsx)
404
+
405
+ ## 🤝 Contributing
406
+
407
+ Contributions welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
408
+
409
+ ## 📄 License
410
+
411
+ JESCON TECHNOLOGIES PVT LTD License - see [LICENSE](./LICENSE) file for details.
412
+
413
+ ## 👨‍💼 Author
414
+
415
+ **PRAFULDAS M M**
416
+ - Company: JESCON TECHNOLOGIES PVT LTD
417
+ - Location: Thrissur, Kerala, India
418
+ - Email: jescontechnologies@gmail.com
419
+
420
+ ## 🔗 Quick Links
421
+
422
+ - [NPM Package](https://www.npmjs.com/package/react-native-vision-camera-spoof-detector)
423
+ - [GitHub Repository](https://github.com/dpraful/react-native-vision-camera-spoof-detector)
424
+ - [React Native Vision Camera](https://react-native-vision-camera.com)
425
+ - [TensorFlow Lite](https://www.tensorflow.org/lite)
426
+
427
+ ## 📞 Support & Community
428
+
429
+ - 🐛 [Report Issues](https://github.com/dpraful/react-native-vision-camera-spoof-detector/issues)
430
+ - 💬 [GitHub Discussions](https://github.com/dpraful/react-native-vision-camera-spoof-detector/discussions)
431
+ - 📧 Email: jescontechnologies@gmail.com
432
+
433
+ ## 🙏 Acknowledgments
434
+
435
+ Built with:
436
+ - [TensorFlow Lite](https://www.tensorflow.org/lite)
437
+ - [React Native Vision Camera](https://react-native-vision-camera.com)
438
+ - [React Native Worklets](https://docs.swmansion.com/react-native-worklets/)
439
+
440
+ ---
441
+
442
+ Made with ❤️ by JESCON TECHNOLOGIES PVT LTD