+3
mobile/composeApp/src/androidMain/kotlin/com/paytondeveloper/myrus_mobile/MLFace.android.kt
+3
mobile/composeApp/src/androidMain/kotlin/com/paytondeveloper/myrus_mobile/MLFace.android.kt
···
27
27
import com.google.mlkit.vision.face.FaceDetector
28
28
import com.google.mlkit.vision.face.FaceDetectorOptions
29
29
import com.google.mlkit.vision.face.FaceDetectorOptions.LandmarkMode
30
+
import com.google.mlkit.vision.face.FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE
30
31
import com.kashif.cameraK.builder.CameraControllerBuilder
31
32
import com.kashif.cameraK.controller.CameraController
32
33
import com.kashif.cameraK.enums.Directory
···
52
53
// val img = InputImage.fromByteArray(img, options.outWidth, options.outHeight, rotationDegrees, InputImage.IMAGE_FORMAT_NV21)
53
54
val bitmap = BitmapFactory.decodeByteArray(img, 0, img.size)
54
55
val img = InputImage.fromBitmap(bitmap, 0)
56
+
val options = FaceDetectorOptions.Builder()
57
+
options.setPerformanceMode(PERFORMANCE_MODE_ACCURATE)
55
58
val detector = FaceDetection.getClient()
56
59
if (AppInfo.canDetectFace) {
57
60
AppInfo.canDetectFace = false
+49
-2
mobile/composeApp/src/commonMain/kotlin/com/paytondeveloper/myrus_mobile/App.kt
+49
-2
mobile/composeApp/src/commonMain/kotlin/com/paytondeveloper/myrus_mobile/App.kt
···
16
16
import androidx.compose.ui.Alignment
17
17
import androidx.compose.ui.Modifier
18
18
import androidx.compose.ui.draw.drawWithCache
19
+
import androidx.compose.ui.draw.scale
19
20
import androidx.compose.ui.geometry.Offset
20
21
import androidx.compose.ui.graphics.Color
21
22
import androidx.compose.ui.graphics.RectangleShape
22
23
import androidx.compose.ui.layout.onSizeChanged
23
24
import androidx.compose.ui.platform.LocalDensity
24
25
import androidx.compose.ui.platform.LocalViewConfiguration
26
+
import androidx.compose.ui.text.font.FontWeight
25
27
import androidx.compose.ui.unit.dp
26
28
import androidx.graphics.shapes.RoundedPolygon
27
29
import com.kashif.cameraK.builder.CameraControllerBuilder
···
54
56
data class Rect(val top: Float, val left: Float, val bottom: Float, val right: Float)
55
57
data class FaceData(val boundingBox: Rect)
56
58
59
+
fun Rect.origin(): Size {
60
+
val midpointX = (this.left + this.right) / 2
61
+
val midpointY = (this.top + this.bottom) / 2
62
+
return Size(width = midpointX, height = midpointY)
63
+
}
64
+
57
65
expect suspend fun sayText(text: String)
58
66
59
67
val genAI = GenerativeModel(
···
63
71
64
72
expect fun epochMillis(): Long
65
73
74
+
enum class MovingDirection {
75
+
RIGHT, LEFT
76
+
}
66
77
67
78
@Composable
68
79
@Preview
···
86
97
var currentThingy by remember { mutableStateOf<Rect?>(Rect(0f,0f,0f,0f)) }
87
98
var delayMillis by remember { mutableStateOf(1000) }
88
99
var analyzing by remember { mutableStateOf(true) }
100
+
var moving by remember { mutableStateOf(false) }
89
101
val tts = rememberTextToSpeechOrNull(TextToSpeechEngine.Google)
102
+
val movingDirection = remember { mutableStateOf<MovingDirection?>(null) }
90
103
LaunchedEffect(Unit) {
91
104
//not proud of this.
92
105
suspend fun roast(image: ByteArray) {
···
123
136
124
137
currentThingy = bounds.copy(top = newY, left = newX)
125
138
analyzing = false
126
-
CoroutineScope(Dispatchers.IO).launch {
127
-
roast(it.byteArray)
139
+
val leftCenter = bounds.right - bounds.left
140
+
println("BOUNDS: ${bounds.origin().width} SIZE: ${size.width}")
141
+
val midpointX = bounds.origin().width
142
+
if (midpointX < ((size.width / 2) - (size.width / 12))) {
143
+
//move left
144
+
println("move left")
145
+
movingDirection.value = MovingDirection.LEFT
146
+
analyzing = true
147
+
} else if (midpointX > ((size.width / 2) + (size.width / 12))) {
148
+
//move right
149
+
println("move right")
150
+
analyzing = true
151
+
movingDirection.value = MovingDirection.RIGHT
152
+
} else {
153
+
movingDirection.value = null
154
+
//centered
155
+
CoroutineScope(Dispatchers.IO).launch {
156
+
roast(it.byteArray)
157
+
}
128
158
}
159
+
129
160
})
130
161
131
162
}
···
145
176
val leftPx = with(LocalDensity.current) {
146
177
currentThingy!!.left.toDp()
147
178
}
179
+
val camSizePx = with(LocalDensity.current) {
180
+
camSize?.width?.toDp() ?: 0.dp
181
+
}
148
182
println("offset (dp) ${topPx} ${leftPx}")
149
183
150
184
CameraPreview(modifier = Modifier.fillMaxSize().onSizeChanged {
···
164
198
}
165
199
})
166
200
Text("Face", modifier = Modifier.offset(x = leftPx, y = topPx))
201
+
// when (movingDirection) {
202
+
// null -> {}
203
+
// MovingDirection.RIGHT {
204
+
// Text(">", fontWeight = FontWeight.Black, color = Color.White)
205
+
// }
206
+
// }
207
+
if (movingDirection.value != null) {
208
+
if (movingDirection.value == MovingDirection.RIGHT) {
209
+
Text(">", fontWeight = FontWeight.Black, color = Color.White, modifier = Modifier.padding(top = 128.dp, start = camSizePx - 64.dp).scale(20f))
210
+
} else {
211
+
Text("<", fontWeight = FontWeight.Black, color = Color.White, modifier = Modifier.padding(top = 128.dp, start = 32.dp).scale(20f))
212
+
}
213
+
}
167
214
}
168
215
Slider(modifier = Modifier.padding(top = 64.dp), value = delayMillis.toFloat(), onValueChange = {
169
216
delayMillis = it.toInt()