@arfuhad/react-native-smart-camera 0.1.1 → 0.1.5
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/CHANGELOG.md +130 -0
- package/README.md +259 -206
- package/android/build.gradle +15 -33
- package/android/src/main/java/com/smartcamera/FaceDetectorFrameProcessorPlugin.kt +324 -0
- package/android/src/main/java/com/smartcamera/SmartCameraPackage.kt +28 -0
- package/build/detection/blinkProcessor.js +2 -1
- package/build/detection/blinkProcessor.js.map +1 -1
- package/build/detection/faceDetector.d.ts +4 -4
- package/build/detection/faceDetector.d.ts.map +1 -1
- package/build/detection/faceDetector.js +31 -11
- package/build/detection/faceDetector.js.map +1 -1
- package/build/detection/index.d.ts +1 -1
- package/build/detection/index.d.ts.map +1 -1
- package/build/detection/index.js +1 -1
- package/build/detection/index.js.map +1 -1
- package/build/detection/staticImageDetector.d.ts +11 -11
- package/build/detection/staticImageDetector.d.ts.map +1 -1
- package/build/detection/staticImageDetector.js +19 -23
- package/build/detection/staticImageDetector.js.map +1 -1
- package/build/hooks/index.d.ts +6 -0
- package/build/hooks/index.d.ts.map +1 -1
- package/build/hooks/index.js +8 -0
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/useBlinkDetection.d.ts +27 -16
- package/build/hooks/useBlinkDetection.d.ts.map +1 -1
- package/build/hooks/useBlinkDetection.js +63 -37
- package/build/hooks/useBlinkDetection.js.map +1 -1
- package/build/hooks/useFaceDetection.js +3 -2
- package/build/hooks/useFaceDetection.js.map +1 -1
- package/build/hooks/useFaceDetector.d.ts +123 -0
- package/build/hooks/useFaceDetector.d.ts.map +1 -0
- package/build/hooks/useFaceDetector.js +133 -0
- package/build/hooks/useFaceDetector.js.map +1 -0
- package/build/hooks/useSmartCamera.js.map +1 -1
- package/build/hooks/useSmartCameraWebRTC.d.ts +3 -5
- package/build/hooks/useSmartCameraWebRTC.d.ts.map +1 -1
- package/build/hooks/useSmartCameraWebRTC.js +19 -87
- package/build/hooks/useSmartCameraWebRTC.js.map +1 -1
- package/build/hooks/useWebRTC.d.ts +88 -0
- package/build/hooks/useWebRTC.d.ts.map +1 -0
- package/build/hooks/useWebRTC.js +394 -0
- package/build/hooks/useWebRTC.js.map +1 -0
- package/build/hooks/useWebRTCWithDetection.d.ts +89 -0
- package/build/hooks/useWebRTCWithDetection.d.ts.map +1 -0
- package/build/hooks/useWebRTCWithDetection.js +131 -0
- package/build/hooks/useWebRTCWithDetection.js.map +1 -0
- package/build/index.d.ts +24 -10
- package/build/index.d.ts.map +1 -1
- package/build/index.js +38 -13
- package/build/index.js.map +1 -1
- package/build/types.d.ts +28 -12
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/build/utils/index.js.map +1 -1
- package/build/webrtc/WebRTCBridge.d.ts +3 -0
- package/build/webrtc/WebRTCBridge.d.ts.map +1 -1
- package/build/webrtc/WebRTCBridge.js +12 -15
- package/build/webrtc/WebRTCBridge.js.map +1 -1
- package/build/webrtc/WebRTCManager.d.ts +148 -0
- package/build/webrtc/WebRTCManager.d.ts.map +1 -0
- package/build/webrtc/WebRTCManager.js +383 -0
- package/build/webrtc/WebRTCManager.js.map +1 -0
- package/build/webrtc/index.d.ts +3 -1
- package/build/webrtc/index.d.ts.map +1 -1
- package/build/webrtc/index.js +5 -0
- package/build/webrtc/index.js.map +1 -1
- package/build/webrtc/types.d.ts +212 -4
- package/build/webrtc/types.d.ts.map +1 -1
- package/build/webrtc/types.js +34 -1
- package/build/webrtc/types.js.map +1 -1
- package/ios/FaceDetectorFrameProcessorPlugin.m +11 -0
- package/ios/FaceDetectorFrameProcessorPlugin.swift +304 -0
- package/package.json +13 -12
- package/react-native-smart-camera.podspec +32 -0
- package/src/detection/blinkProcessor.ts +127 -0
- package/src/detection/faceDetector.ts +78 -0
- package/src/detection/index.ts +3 -0
- package/src/detection/staticImageDetector.ts +53 -0
- package/src/hooks/index.ts +26 -0
- package/src/hooks/useBlinkDetection.ts +127 -0
- package/src/hooks/useFaceDetection.ts +105 -0
- package/src/hooks/useFaceDetector.ts +191 -0
- package/src/hooks/useSmartCamera.ts +83 -0
- package/src/hooks/useSmartCameraWebRTC.ts +120 -0
- package/src/hooks/useWebRTC.ts +453 -0
- package/src/hooks/useWebRTCWithDetection.ts +181 -0
- package/src/index.ts +170 -0
- package/src/types.ts +636 -0
- package/src/utils/index.ts +355 -0
- package/src/webrtc/WebRTCBridge.ts +127 -0
- package/src/webrtc/WebRTCManager.ts +453 -0
- package/src/webrtc/index.ts +50 -0
- package/src/webrtc/types.ts +361 -0
- package/android/src/main/java/expo/modules/smartcamera/ImageLoader.kt +0 -106
- package/android/src/main/java/expo/modules/smartcamera/MLKitFaceDetector.kt +0 -273
- package/android/src/main/java/expo/modules/smartcamera/SmartCameraModule.kt +0 -205
- package/android/src/main/java/expo/modules/smartcamera/SmartCameraView.kt +0 -153
- package/android/src/main/java/expo/modules/smartcamera/WebRTCFrameBridge.kt +0 -184
- package/build/SmartCamera.d.ts +0 -17
- package/build/SmartCamera.d.ts.map +0 -1
- package/build/SmartCamera.js +0 -270
- package/build/SmartCamera.js.map +0 -1
- package/build/SmartCameraModule.d.ts +0 -112
- package/build/SmartCameraModule.d.ts.map +0 -1
- package/build/SmartCameraModule.js +0 -121
- package/build/SmartCameraModule.js.map +0 -1
- package/build/SmartCameraView.d.ts +0 -8
- package/build/SmartCameraView.d.ts.map +0 -1
- package/build/SmartCameraView.js +0 -7
- package/build/SmartCameraView.js.map +0 -1
- package/expo-module.config.json +0 -9
- package/ios/MLKitFaceDetector.swift +0 -310
- package/ios/SmartCamera.podspec +0 -33
- package/ios/SmartCameraModule.swift +0 -225
- package/ios/SmartCameraView.swift +0 -146
- package/ios/WebRTCFrameBridge.swift +0 -150
package/android/build.gradle
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
apply plugin: 'kotlin-android'
|
|
3
|
-
apply plugin: 'maven-publish'
|
|
4
3
|
|
|
5
|
-
group = '
|
|
6
|
-
version = '0.1.
|
|
4
|
+
group = 'com.smartcamera'
|
|
5
|
+
version = '0.1.4'
|
|
7
6
|
|
|
8
7
|
buildscript {
|
|
9
|
-
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
10
|
-
if (expoModulesCorePlugin.exists()) {
|
|
11
|
-
apply from: expoModulesCorePlugin
|
|
12
|
-
applyKotlinExpoModulesCorePlugin()
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Simple fallback that allows building without expo-modules-core for lint
|
|
16
8
|
repositories {
|
|
17
9
|
mavenCentral()
|
|
18
10
|
google()
|
|
@@ -23,23 +15,8 @@ buildscript {
|
|
|
23
15
|
}
|
|
24
16
|
}
|
|
25
17
|
|
|
26
|
-
afterEvaluate {
|
|
27
|
-
publishing {
|
|
28
|
-
publications {
|
|
29
|
-
release(MavenPublication) {
|
|
30
|
-
from components.release
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
repositories {
|
|
34
|
-
maven {
|
|
35
|
-
url = mavenLocal().url
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
18
|
android {
|
|
42
|
-
namespace "
|
|
19
|
+
namespace "com.smartcamera"
|
|
43
20
|
compileSdkVersion safeExtGet("compileSdkVersion", 34)
|
|
44
21
|
|
|
45
22
|
defaultConfig {
|
|
@@ -47,12 +24,6 @@ android {
|
|
|
47
24
|
targetSdkVersion safeExtGet("targetSdkVersion", 34)
|
|
48
25
|
}
|
|
49
26
|
|
|
50
|
-
publishing {
|
|
51
|
-
singleVariant("release") {
|
|
52
|
-
withSourcesJar()
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
27
|
lintOptions {
|
|
57
28
|
abortOnError false
|
|
58
29
|
}
|
|
@@ -65,6 +36,12 @@ android {
|
|
|
65
36
|
kotlinOptions {
|
|
66
37
|
jvmTarget = JavaVersion.VERSION_17.majorVersion
|
|
67
38
|
}
|
|
39
|
+
|
|
40
|
+
sourceSets {
|
|
41
|
+
main {
|
|
42
|
+
java.srcDirs = ['src/main/java']
|
|
43
|
+
}
|
|
44
|
+
}
|
|
68
45
|
}
|
|
69
46
|
|
|
70
47
|
repositories {
|
|
@@ -73,7 +50,6 @@ repositories {
|
|
|
73
50
|
}
|
|
74
51
|
|
|
75
52
|
dependencies {
|
|
76
|
-
implementation project(':expo-modules-core')
|
|
77
53
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.22"
|
|
78
54
|
|
|
79
55
|
// Kotlin Coroutines
|
|
@@ -82,6 +58,12 @@ dependencies {
|
|
|
82
58
|
|
|
83
59
|
// Google ML Kit Face Detection
|
|
84
60
|
implementation 'com.google.mlkit:face-detection:16.1.6'
|
|
61
|
+
|
|
62
|
+
// VisionCamera Frame Processor API (compileOnly - provided by peer dependency)
|
|
63
|
+
compileOnly project(':react-native-vision-camera')
|
|
64
|
+
|
|
65
|
+
// React Native
|
|
66
|
+
compileOnly "com.facebook.react:react-android:+"
|
|
85
67
|
}
|
|
86
68
|
|
|
87
69
|
def safeExtGet(prop, fallback) {
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
package com.smartcamera
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.google.android.gms.tasks.Tasks
|
|
5
|
+
import com.google.mlkit.vision.common.InputImage
|
|
6
|
+
import com.google.mlkit.vision.face.Face
|
|
7
|
+
import com.google.mlkit.vision.face.FaceContour
|
|
8
|
+
import com.google.mlkit.vision.face.FaceDetection
|
|
9
|
+
import com.google.mlkit.vision.face.FaceDetector
|
|
10
|
+
import com.google.mlkit.vision.face.FaceDetectorOptions
|
|
11
|
+
import com.google.mlkit.vision.face.FaceLandmark
|
|
12
|
+
import com.mrousavy.camera.frameprocessors.Frame
|
|
13
|
+
import com.mrousavy.camera.frameprocessors.FrameProcessorPlugin
|
|
14
|
+
import com.mrousavy.camera.frameprocessors.VisionCameraProxy
|
|
15
|
+
|
|
16
|
+
// Data class to track current options for comparison
|
|
17
|
+
private data class DetectorConfig(
|
|
18
|
+
val performanceMode: String,
|
|
19
|
+
val landmarkMode: String,
|
|
20
|
+
val contourMode: String,
|
|
21
|
+
val classificationMode: String,
|
|
22
|
+
val minFaceSize: Float,
|
|
23
|
+
val trackingEnabled: Boolean,
|
|
24
|
+
val autoMode: Boolean,
|
|
25
|
+
val windowWidth: Float,
|
|
26
|
+
val windowHeight: Float,
|
|
27
|
+
val cameraFacing: String
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
class FaceDetectorFrameProcessorPlugin(proxy: VisionCameraProxy, options: Map<String, Any>?) : FrameProcessorPlugin() {
|
|
31
|
+
|
|
32
|
+
companion object {
|
|
33
|
+
private const val TAG = "FaceDetectorPlugin"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private var faceDetector: FaceDetector? = null
|
|
37
|
+
private var currentConfig: DetectorConfig? = null
|
|
38
|
+
|
|
39
|
+
init {
|
|
40
|
+
Log.d(TAG, "FaceDetectorFrameProcessorPlugin initialized")
|
|
41
|
+
updateDetectorOptions(options ?: emptyMap())
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private fun updateDetectorOptions(options: Map<String, Any>) {
|
|
45
|
+
val performanceMode = options["performanceMode"] as? String ?: "fast"
|
|
46
|
+
val landmarkMode = options["landmarkMode"] as? String ?: "none"
|
|
47
|
+
val contourMode = options["contourMode"] as? String ?: "none"
|
|
48
|
+
val classificationMode = options["classificationMode"] as? String ?: "none"
|
|
49
|
+
val minFaceSize = (options["minFaceSize"] as? Number)?.toFloat() ?: 0.15f
|
|
50
|
+
val trackingEnabled = options["trackingEnabled"] as? Boolean ?: false
|
|
51
|
+
val autoMode = options["autoMode"] as? Boolean ?: false
|
|
52
|
+
val windowWidth = (options["windowWidth"] as? Number)?.toFloat() ?: 1.0f
|
|
53
|
+
val windowHeight = (options["windowHeight"] as? Number)?.toFloat() ?: 1.0f
|
|
54
|
+
val cameraFacing = options["cameraFacing"] as? String ?: "front"
|
|
55
|
+
|
|
56
|
+
val newConfig = DetectorConfig(
|
|
57
|
+
performanceMode = performanceMode,
|
|
58
|
+
landmarkMode = landmarkMode,
|
|
59
|
+
contourMode = contourMode,
|
|
60
|
+
classificationMode = classificationMode,
|
|
61
|
+
minFaceSize = minFaceSize,
|
|
62
|
+
trackingEnabled = trackingEnabled,
|
|
63
|
+
autoMode = autoMode,
|
|
64
|
+
windowWidth = windowWidth,
|
|
65
|
+
windowHeight = windowHeight,
|
|
66
|
+
cameraFacing = cameraFacing
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
// Only recreate detector if core options changed
|
|
70
|
+
if (currentConfig != null &&
|
|
71
|
+
currentConfig!!.performanceMode == newConfig.performanceMode &&
|
|
72
|
+
currentConfig!!.landmarkMode == newConfig.landmarkMode &&
|
|
73
|
+
currentConfig!!.contourMode == newConfig.contourMode &&
|
|
74
|
+
currentConfig!!.classificationMode == newConfig.classificationMode &&
|
|
75
|
+
currentConfig!!.minFaceSize == newConfig.minFaceSize &&
|
|
76
|
+
currentConfig!!.trackingEnabled == newConfig.trackingEnabled) {
|
|
77
|
+
// Only update non-detector options
|
|
78
|
+
currentConfig = newConfig
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
val optionsBuilder = FaceDetectorOptions.Builder()
|
|
83
|
+
|
|
84
|
+
when (performanceMode) {
|
|
85
|
+
"accurate" -> optionsBuilder.setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
|
|
86
|
+
else -> optionsBuilder.setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
when (landmarkMode) {
|
|
90
|
+
"all" -> optionsBuilder.setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL)
|
|
91
|
+
else -> optionsBuilder.setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_NONE)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
when (contourMode) {
|
|
95
|
+
"all" -> optionsBuilder.setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
|
|
96
|
+
else -> optionsBuilder.setContourMode(FaceDetectorOptions.CONTOUR_MODE_NONE)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
when (classificationMode) {
|
|
100
|
+
"all" -> optionsBuilder.setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
|
|
101
|
+
else -> optionsBuilder.setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_NONE)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
optionsBuilder.setMinFaceSize(minFaceSize)
|
|
105
|
+
|
|
106
|
+
if (trackingEnabled) {
|
|
107
|
+
optionsBuilder.enableTracking()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
faceDetector?.close()
|
|
111
|
+
faceDetector = FaceDetection.getClient(optionsBuilder.build())
|
|
112
|
+
currentConfig = newConfig
|
|
113
|
+
Log.d(TAG, "Face detector updated with new options")
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
override fun callback(frame: Frame, arguments: Map<String, Any>?): Any {
|
|
117
|
+
if (arguments != null && arguments.isNotEmpty()) {
|
|
118
|
+
updateDetectorOptions(arguments)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
val detector = faceDetector ?: run {
|
|
122
|
+
Log.e(TAG, "Face detector not initialized")
|
|
123
|
+
return emptyList<Map<String, Any>>()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
val config = currentConfig ?: return emptyList<Map<String, Any>>()
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
val mediaImage = frame.image
|
|
130
|
+
val inputImage = InputImage.fromMediaImage(
|
|
131
|
+
mediaImage,
|
|
132
|
+
frame.orientation.toDegrees()
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
val faces = Tasks.await(detector.process(inputImage))
|
|
136
|
+
|
|
137
|
+
return faces.map { face ->
|
|
138
|
+
faceToMap(
|
|
139
|
+
face,
|
|
140
|
+
frame.width,
|
|
141
|
+
frame.height,
|
|
142
|
+
config.autoMode,
|
|
143
|
+
config.windowWidth,
|
|
144
|
+
config.windowHeight,
|
|
145
|
+
config.cameraFacing
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
} catch (e: Exception) {
|
|
149
|
+
Log.e(TAG, "Face detection error: ${e.message}")
|
|
150
|
+
return emptyList<Map<String, Any>>()
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private fun faceToMap(
|
|
155
|
+
face: Face,
|
|
156
|
+
frameWidth: Int,
|
|
157
|
+
frameHeight: Int,
|
|
158
|
+
autoMode: Boolean,
|
|
159
|
+
windowWidth: Float,
|
|
160
|
+
windowHeight: Float,
|
|
161
|
+
cameraFacing: String
|
|
162
|
+
): Map<String, Any> {
|
|
163
|
+
val result = mutableMapOf<String, Any>()
|
|
164
|
+
|
|
165
|
+
// Calculate scale factors for autoMode
|
|
166
|
+
val scaleX = if (autoMode) windowWidth / frameWidth else 1.0f / frameWidth
|
|
167
|
+
val scaleY = if (autoMode) windowHeight / frameHeight else 1.0f / frameHeight
|
|
168
|
+
val mirrorX = autoMode && cameraFacing == "front"
|
|
169
|
+
|
|
170
|
+
// Bounding box
|
|
171
|
+
val bounds = face.boundingBox
|
|
172
|
+
val x = if (mirrorX) {
|
|
173
|
+
windowWidth - (bounds.right * scaleX)
|
|
174
|
+
} else {
|
|
175
|
+
bounds.left * scaleX
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
result["bounds"] = mapOf(
|
|
179
|
+
"x" to x.toDouble(),
|
|
180
|
+
"y" to (bounds.top * scaleY).toDouble(),
|
|
181
|
+
"width" to (bounds.width() * scaleX).toDouble(),
|
|
182
|
+
"height" to (bounds.height() * scaleY).toDouble()
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
// Roll, pitch, yaw angles
|
|
186
|
+
result["rollAngle"] = face.headEulerAngleZ.toDouble()
|
|
187
|
+
result["pitchAngle"] = face.headEulerAngleX.toDouble()
|
|
188
|
+
result["yawAngle"] = face.headEulerAngleY.toDouble()
|
|
189
|
+
|
|
190
|
+
// Classification probabilities
|
|
191
|
+
face.smilingProbability?.let { result["smilingProbability"] = it.toDouble() }
|
|
192
|
+
face.leftEyeOpenProbability?.let { result["leftEyeOpenProbability"] = it.toDouble() }
|
|
193
|
+
face.rightEyeOpenProbability?.let { result["rightEyeOpenProbability"] = it.toDouble() }
|
|
194
|
+
|
|
195
|
+
// Tracking ID
|
|
196
|
+
face.trackingId?.let { result["trackingId"] = it }
|
|
197
|
+
|
|
198
|
+
// Landmarks
|
|
199
|
+
val landmarks = mutableMapOf<String, Any>()
|
|
200
|
+
|
|
201
|
+
face.getLandmark(FaceLandmark.LEFT_EYE)?.let {
|
|
202
|
+
landmarks["leftEye"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
203
|
+
}
|
|
204
|
+
face.getLandmark(FaceLandmark.RIGHT_EYE)?.let {
|
|
205
|
+
landmarks["rightEye"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
206
|
+
}
|
|
207
|
+
face.getLandmark(FaceLandmark.NOSE_BASE)?.let {
|
|
208
|
+
landmarks["noseBase"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
209
|
+
}
|
|
210
|
+
face.getLandmark(FaceLandmark.LEFT_CHEEK)?.let {
|
|
211
|
+
landmarks["leftCheek"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
212
|
+
}
|
|
213
|
+
face.getLandmark(FaceLandmark.RIGHT_CHEEK)?.let {
|
|
214
|
+
landmarks["rightCheek"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
215
|
+
}
|
|
216
|
+
face.getLandmark(FaceLandmark.MOUTH_LEFT)?.let {
|
|
217
|
+
landmarks["mouthLeft"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
218
|
+
}
|
|
219
|
+
face.getLandmark(FaceLandmark.MOUTH_RIGHT)?.let {
|
|
220
|
+
landmarks["mouthRight"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
221
|
+
}
|
|
222
|
+
face.getLandmark(FaceLandmark.MOUTH_BOTTOM)?.let {
|
|
223
|
+
landmarks["mouthBottom"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
224
|
+
}
|
|
225
|
+
face.getLandmark(FaceLandmark.LEFT_EAR)?.let {
|
|
226
|
+
landmarks["leftEar"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
227
|
+
}
|
|
228
|
+
face.getLandmark(FaceLandmark.RIGHT_EAR)?.let {
|
|
229
|
+
landmarks["rightEar"] = pointToMap(it.position.x, it.position.y, scaleX, scaleY, mirrorX, windowWidth)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (landmarks.isNotEmpty()) {
|
|
233
|
+
result["landmarks"] = landmarks
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// All contours (like reference package)
|
|
237
|
+
val contours = mutableMapOf<String, Any>()
|
|
238
|
+
|
|
239
|
+
face.getContour(FaceContour.FACE)?.let { contour ->
|
|
240
|
+
contours["face"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
241
|
+
}
|
|
242
|
+
face.getContour(FaceContour.LEFT_EYEBROW_TOP)?.let { contour ->
|
|
243
|
+
contours["leftEyebrowTop"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
244
|
+
}
|
|
245
|
+
face.getContour(FaceContour.LEFT_EYEBROW_BOTTOM)?.let { contour ->
|
|
246
|
+
contours["leftEyebrowBottom"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
247
|
+
}
|
|
248
|
+
face.getContour(FaceContour.RIGHT_EYEBROW_TOP)?.let { contour ->
|
|
249
|
+
contours["rightEyebrowTop"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
250
|
+
}
|
|
251
|
+
face.getContour(FaceContour.RIGHT_EYEBROW_BOTTOM)?.let { contour ->
|
|
252
|
+
contours["rightEyebrowBottom"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
253
|
+
}
|
|
254
|
+
face.getContour(FaceContour.LEFT_EYE)?.let { contour ->
|
|
255
|
+
contours["leftEye"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
256
|
+
}
|
|
257
|
+
face.getContour(FaceContour.RIGHT_EYE)?.let { contour ->
|
|
258
|
+
contours["rightEye"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
259
|
+
}
|
|
260
|
+
face.getContour(FaceContour.UPPER_LIP_TOP)?.let { contour ->
|
|
261
|
+
contours["upperLipTop"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
262
|
+
}
|
|
263
|
+
face.getContour(FaceContour.UPPER_LIP_BOTTOM)?.let { contour ->
|
|
264
|
+
contours["upperLipBottom"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
265
|
+
}
|
|
266
|
+
face.getContour(FaceContour.LOWER_LIP_TOP)?.let { contour ->
|
|
267
|
+
contours["lowerLipTop"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
268
|
+
}
|
|
269
|
+
face.getContour(FaceContour.LOWER_LIP_BOTTOM)?.let { contour ->
|
|
270
|
+
contours["lowerLipBottom"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
271
|
+
}
|
|
272
|
+
face.getContour(FaceContour.NOSE_BRIDGE)?.let { contour ->
|
|
273
|
+
contours["noseBridge"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
274
|
+
}
|
|
275
|
+
face.getContour(FaceContour.NOSE_BOTTOM)?.let { contour ->
|
|
276
|
+
contours["noseBottom"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
277
|
+
}
|
|
278
|
+
face.getContour(FaceContour.LEFT_CHEEK)?.let { contour ->
|
|
279
|
+
contours["leftCheek"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
280
|
+
}
|
|
281
|
+
face.getContour(FaceContour.RIGHT_CHEEK)?.let { contour ->
|
|
282
|
+
contours["rightCheek"] = contour.points.map { p -> pointToMap(p.x, p.y, scaleX, scaleY, mirrorX, windowWidth) }
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (contours.isNotEmpty()) {
|
|
286
|
+
result["contours"] = contours
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return result
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private fun pointToMap(
|
|
293
|
+
x: Float,
|
|
294
|
+
y: Float,
|
|
295
|
+
scaleX: Float,
|
|
296
|
+
scaleY: Float,
|
|
297
|
+
mirrorX: Boolean,
|
|
298
|
+
windowWidth: Float
|
|
299
|
+
): Map<String, Double> {
|
|
300
|
+
val scaledX = if (mirrorX) {
|
|
301
|
+
windowWidth - (x * scaleX)
|
|
302
|
+
} else {
|
|
303
|
+
x * scaleX
|
|
304
|
+
}
|
|
305
|
+
return mapOf(
|
|
306
|
+
"x" to scaledX.toDouble(),
|
|
307
|
+
"y" to (y * scaleY).toDouble()
|
|
308
|
+
)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private fun com.mrousavy.camera.core.types.Orientation.toDegrees(): Int {
|
|
312
|
+
return when (this) {
|
|
313
|
+
com.mrousavy.camera.core.types.Orientation.PORTRAIT -> 0
|
|
314
|
+
com.mrousavy.camera.core.types.Orientation.LANDSCAPE_LEFT -> 90
|
|
315
|
+
com.mrousavy.camera.core.types.Orientation.PORTRAIT_UPSIDE_DOWN -> 180
|
|
316
|
+
com.mrousavy.camera.core.types.Orientation.LANDSCAPE_RIGHT -> 270
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
protected fun finalize() {
|
|
321
|
+
faceDetector?.close()
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package com.smartcamera
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
import com.mrousavy.camera.frameprocessors.FrameProcessorPluginRegistry
|
|
8
|
+
|
|
9
|
+
class SmartCameraPackage : ReactPackage {
|
|
10
|
+
|
|
11
|
+
companion object {
|
|
12
|
+
init {
|
|
13
|
+
// Register the frame processor plugin with VisionCamera
|
|
14
|
+
FrameProcessorPluginRegistry.addFrameProcessorPlugin("detectFaces") { proxy, options ->
|
|
15
|
+
FaceDetectorFrameProcessorPlugin(proxy, options)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
21
|
+
return emptyList()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
25
|
+
return emptyList()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
@@ -18,6 +18,7 @@ const blinkStates = new Map();
|
|
|
18
18
|
*/
|
|
19
19
|
export function processBlinkFromFaces(faces, lastBlinkTimestamp, debounceMs = 300) {
|
|
20
20
|
'worklet';
|
|
21
|
+
var _a;
|
|
21
22
|
if (faces.length === 0) {
|
|
22
23
|
return null;
|
|
23
24
|
}
|
|
@@ -32,7 +33,7 @@ export function processBlinkFromFaces(faces, lastBlinkTimestamp, debounceMs = 30
|
|
|
32
33
|
const rightEyeOpen = face.rightEyeOpenProbability;
|
|
33
34
|
const now = Date.now();
|
|
34
35
|
// Get or create blink state for this face
|
|
35
|
-
const faceId = face.trackingId
|
|
36
|
+
const faceId = (_a = face.trackingId) !== null && _a !== void 0 ? _a : 0;
|
|
36
37
|
let state = blinkStates.get(faceId);
|
|
37
38
|
if (!state) {
|
|
38
39
|
state = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blinkProcessor.js","sourceRoot":"","sources":["../../src/detection/blinkProcessor.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC;;GAEG;AACH,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAU/B,0CAA0C;AAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,kBAA0B,EAC1B,aAAqB,GAAG;IAExB,SAAS,CAAC
|
|
1
|
+
{"version":3,"file":"blinkProcessor.js","sourceRoot":"","sources":["../../src/detection/blinkProcessor.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC;;GAEG;AACH,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAU/B,0CAA0C;AAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,kBAA0B,EAC1B,aAAqB,GAAG;IAExB,SAAS,CAAC;;IAEV,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtB,yCAAyC;IACzC,IACE,IAAI,CAAC,sBAAsB,KAAK,SAAS;QACzC,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,uBAAuB,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,0CAA0C;IAC1C,MAAM,MAAM,GAAG,MAAA,IAAI,CAAC,UAAU,mCAAI,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG;YACN,aAAa,EAAE,KAAK;YACpB,kBAAkB,EAAE,CAAC;SACtB,CAAC;QACF,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,qCAAqC;IACrC,MAAM,UAAU,GAAG,WAAW,GAAG,oBAAoB,IAAI,YAAY,GAAG,oBAAoB,CAAC;IAE7F,mCAAmC;IACnC,MAAM,QAAQ,GAAG,WAAW,GAAG,kBAAkB,IAAI,YAAY,GAAG,kBAAkB,CAAC;IAEvF,+CAA+C;IAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,IAAI,QAAQ,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,kBAAkB,CAAC,GAAG,UAAU,CAAC;IAEjG,eAAe;IACf,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;IAC7B,CAAC;SAAM,IAAI,QAAQ,EAAE,CAAC;QACpB,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC;QAE/B,OAAO;YACL,SAAS,EAAE,GAAG;YACd,WAAW;YACX,YAAY;YACZ,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,IAAI,CAAC,UAAU;SACxB,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAU;IACpC,SAAS,CAAC;IAEV,IACE,IAAI,CAAC,sBAAsB,KAAK,SAAS;QACzC,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,sBAAsB;QACrC,SAAS,EAAE,IAAI,CAAC,uBAAuB;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Frame } from 'react-native-vision-camera';
|
|
2
2
|
import type { Face, FrameProcessorOptions } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* Detect faces in a camera frame
|
|
@@ -9,8 +9,8 @@ import type { Face, FrameProcessorOptions } from '../types';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function detectFaces(frame: Frame, options?: Partial<FrameProcessorOptions>): Face[];
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Check if the face detector plugin is available
|
|
13
|
+
* @returns true if the plugin is registered and available
|
|
14
14
|
*/
|
|
15
|
-
export declare function
|
|
15
|
+
export declare function isFaceDetectorAvailable(): boolean;
|
|
16
16
|
//# sourceMappingURL=faceDetector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"faceDetector.d.ts","sourceRoot":"","sources":["../../src/detection/faceDetector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"faceDetector.d.ts","sourceRoot":"","sources":["../../src/detection/faceDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,KAAK,EAAE,IAAI,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAwB5D;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,IAAI,EAAE,CAmC1F;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { VisionCameraProxy } from 'react-native-vision-camera';
|
|
2
|
+
/**
|
|
3
|
+
* Initialize the face detector frame processor plugin
|
|
4
|
+
* This registers the native plugin with VisionCamera
|
|
5
|
+
*/
|
|
6
|
+
const plugin = VisionCameraProxy.initFrameProcessorPlugin('detectFaces', {});
|
|
1
7
|
/**
|
|
2
8
|
* Default face detection options
|
|
3
9
|
*/
|
|
@@ -22,12 +28,28 @@ const DEFAULT_OPTIONS = {
|
|
|
22
28
|
*/
|
|
23
29
|
export function detectFaces(frame, options) {
|
|
24
30
|
'worklet';
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
if (plugin == null) {
|
|
32
|
+
// Plugin not available - return empty array
|
|
33
|
+
// This can happen if the native module is not properly linked
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const mergedOptions = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
|
|
29
37
|
try {
|
|
30
|
-
|
|
38
|
+
// Convert options to a format compatible with VisionCamera plugin API
|
|
39
|
+
const pluginOptions = {
|
|
40
|
+
performanceMode: mergedOptions.performanceMode,
|
|
41
|
+
landmarkMode: mergedOptions.landmarkMode,
|
|
42
|
+
contourMode: mergedOptions.contourMode,
|
|
43
|
+
classificationMode: mergedOptions.classificationMode,
|
|
44
|
+
minFaceSize: mergedOptions.minFaceSize,
|
|
45
|
+
trackingEnabled: mergedOptions.trackingEnabled,
|
|
46
|
+
cameraFacing: mergedOptions.cameraFacing,
|
|
47
|
+
autoMode: mergedOptions.autoMode,
|
|
48
|
+
windowWidth: mergedOptions.windowWidth,
|
|
49
|
+
windowHeight: mergedOptions.windowHeight,
|
|
50
|
+
};
|
|
51
|
+
const result = plugin.call(frame, pluginOptions);
|
|
52
|
+
return result !== null && result !== void 0 ? result : [];
|
|
31
53
|
}
|
|
32
54
|
catch (error) {
|
|
33
55
|
// Return empty array on error in worklet context
|
|
@@ -35,12 +57,10 @@ export function detectFaces(frame, options) {
|
|
|
35
57
|
}
|
|
36
58
|
}
|
|
37
59
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
60
|
+
* Check if the face detector plugin is available
|
|
61
|
+
* @returns true if the plugin is registered and available
|
|
40
62
|
*/
|
|
41
|
-
export function
|
|
42
|
-
|
|
43
|
-
// through the Expo module system
|
|
44
|
-
console.log('[SmartCamera] Face detector plugin registered');
|
|
63
|
+
export function isFaceDetectorAvailable() {
|
|
64
|
+
return plugin != null;
|
|
45
65
|
}
|
|
46
66
|
//# sourceMappingURL=faceDetector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"faceDetector.js","sourceRoot":"","sources":["../../src/detection/faceDetector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"faceDetector.js","sourceRoot":"","sources":["../../src/detection/faceDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAc,MAAM,4BAA4B,CAAC;AAG3E;;;GAGG;AACH,MAAM,MAAM,GAAG,iBAAiB,CAAC,wBAAwB,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AAE7E;;GAEG;AACH,MAAM,eAAe,GAA0B;IAC7C,eAAe,EAAE,MAAM;IACvB,YAAY,EAAE,MAAM;IACpB,WAAW,EAAE,MAAM;IACnB,kBAAkB,EAAE,MAAM;IAC1B,WAAW,EAAE,IAAI;IACjB,eAAe,EAAE,KAAK;IACtB,YAAY,EAAE,OAAO;IACrB,QAAQ,EAAE,KAAK;IACf,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,GAAG;CAClB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,OAAwC;IAChF,SAAS,CAAC;IAEV,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,4CAA4C;QAC5C,8DAA8D;QAC9D,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,aAAa,mCACd,eAAe,GACf,OAAO,CACX,CAAC;IAEF,IAAI,CAAC;QACH,sEAAsE;QACtE,MAAM,aAAa,GAA0D;YAC3E,eAAe,EAAE,aAAa,CAAC,eAAe;YAC9C,YAAY,EAAE,aAAa,CAAC,YAAY;YACxC,WAAW,EAAE,aAAa,CAAC,WAAW;YACtC,kBAAkB,EAAE,aAAa,CAAC,kBAAkB;YACpD,WAAW,EAAE,aAAa,CAAC,WAAW;YACtC,eAAe,EAAE,aAAa,CAAC,eAAe;YAC9C,YAAY,EAAE,aAAa,CAAC,YAAY;YACxC,QAAQ,EAAE,aAAa,CAAC,QAAQ;YAChC,WAAW,EAAE,aAAa,CAAC,WAAW;YACtC,YAAY,EAAE,aAAa,CAAC,YAAY;SACzC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,CAA8B,CAAC;QAC9E,OAAO,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iDAAiD;QACjD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,MAAM,IAAI,IAAI,CAAC;AACxB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { detectFaces,
|
|
1
|
+
export { detectFaces, isFaceDetectorAvailable } from './faceDetector';
|
|
2
2
|
export { processBlinkFromFaces, resetBlinkStates, getEyeState } from './blinkProcessor';
|
|
3
3
|
export { detectFacesInImage } from './staticImageDetector';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/build/detection/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { detectFaces,
|
|
1
|
+
export { detectFaces, isFaceDetectorAvailable } from './faceDetector';
|
|
2
2
|
export { processBlinkFromFaces, resetBlinkStates, getEyeState } from './blinkProcessor';
|
|
3
3
|
export { detectFacesInImage } from './staticImageDetector';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -2,23 +2,23 @@ import type { Face, StaticImageOptions } from '../types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Detect faces in a static image
|
|
4
4
|
*
|
|
5
|
+
* NOTE: Static image detection is currently not supported in the frame processor-only version.
|
|
6
|
+
* This feature requires native module implementation.
|
|
7
|
+
* For real-time face detection, use the `detectFaces` function with VisionCamera frame processor.
|
|
8
|
+
*
|
|
5
9
|
* @param options - Image source and detection options
|
|
6
10
|
* @returns Promise resolving to array of detected faces
|
|
7
11
|
*
|
|
8
12
|
* @example
|
|
9
13
|
* ```tsx
|
|
10
|
-
* //
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* performanceMode: 'accurate',
|
|
14
|
-
* landmarkMode: 'all',
|
|
15
|
-
* });
|
|
14
|
+
* // This feature is not yet implemented
|
|
15
|
+
* // For real-time detection, use:
|
|
16
|
+
* import { detectFaces } from '@arfuhad/react-native-smart-camera';
|
|
16
17
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* });
|
|
18
|
+
* const frameProcessor = useFrameProcessor((frame) => {
|
|
19
|
+
* 'worklet';
|
|
20
|
+
* const faces = detectFaces(frame);
|
|
21
|
+
* }, []);
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export declare function detectFacesInImage(options: StaticImageOptions): Promise<Face[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staticImageDetector.d.ts","sourceRoot":"","sources":["../../src/detection/staticImageDetector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"staticImageDetector.d.ts","sourceRoot":"","sources":["../../src/detection/staticImageDetector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAczD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAgBrF"}
|