This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

fix: handle device rotation

+47 -2
+6 -2
posedetection/src/androidMain/kotlin/com/performancecoachlab/posedetection/camera/Utils.android.kt
··· 108 108 * @param angle The rotation angle in degrees (must be a multiple of 90) to apply to the focus area rectangle 109 109 * @return A new bitmap with areas outside the focus area blacked out, or the original bitmap if focusArea is null 110 110 */ 111 - fun Bitmap.applyFocusAreaMask(focusArea: Rect?, angle: Int = 0): Bitmap { 111 + fun Bitmap.applyFocusAreaMask(focusArea: Rect?, _angle: Int = 0): Bitmap { 112 112 return focusArea?.let { rect -> 113 113 val result = this.copy(this.config ?: Bitmap.Config.ARGB_8888, true) 114 114 val canvas = android.graphics.Canvas(result) ··· 116 116 color = android.graphics.Color.BLACK 117 117 } 118 118 119 + val angle = 0 119 120 // Transform the rectangle coordinates based on the angle 120 121 val transformedRect = when (angle % 360) { 121 122 90 -> Rect( ··· 201 202 } ?: emptyList() 202 203 var skeleton: Skeleton? = null 203 204 val poseDetectionTask = mlKitImage?.let { 205 + val rotation = it.rotationDegrees 204 206 poseDetector?.process(it)?.addOnSuccessListener { pose -> 205 - skeleton = skeleton(pose, timestamp, width, height) 207 + skeleton = skeleton(pose, timestamp, width, height).let{ 208 + it.rotate(rotation) 209 + } 206 210 }?.addOnFailureListener { e -> 207 211 //println(e) 208 212 }
+40
posedetection/src/commonMain/kotlin/com/performancecoachlab/posedetection/skeleton/Skeleton.kt
··· 174 174 height = height, 175 175 ) 176 176 } 177 + 178 + fun rotate(angle: Int): Skeleton { 179 + if (angle % 90 != 0) return this 180 + 181 + val normalizedAngle = ((angle % 360) + 360) % 360 182 + if (normalizedAngle == 0) return this 183 + 184 + val frameWidth = this.width 185 + val frameHeight = this.height 186 + 187 + val transform: (SkeletonCoordinate) -> SkeletonCoordinate = when (normalizedAngle) { 188 + 90 -> { coord -> SkeletonCoordinate(coord.y, frameWidth - coord.x) } 189 + 180 -> { coord -> SkeletonCoordinate(frameWidth - coord.x, frameHeight - coord.y) } 190 + 270 -> { coord -> SkeletonCoordinate(frameHeight - coord.y, coord.x) } 191 + else -> { coord -> coord } 192 + } 193 + 194 + val newDimensions = when (normalizedAngle) { 195 + 90, 270 -> Pair(frameHeight, frameWidth) 196 + else -> Pair(frameWidth, frameHeight) 197 + } 198 + 199 + return Skeleton( 200 + timestamp = timestamp, 201 + leftShoulder = leftShoulder?.let(transform), 202 + rightShoulder = rightShoulder?.let(transform), 203 + leftElbow = leftElbow?.let(transform), 204 + rightElbow = rightElbow?.let(transform), 205 + leftWrist = leftWrist?.let(transform), 206 + rightWrist = rightWrist?.let(transform), 207 + leftHip = leftHip?.let(transform), 208 + rightHip = rightHip?.let(transform), 209 + leftKnee = leftKnee?.let(transform), 210 + rightKnee = rightKnee?.let(transform), 211 + leftAnkle = leftAnkle?.let(transform), 212 + rightAnkle = rightAnkle?.let(transform), 213 + width = newDimensions.first, 214 + height = newDimensions.second 215 + ) 216 + } 177 217 }
+1
sample/composeApp/src/commonMain/kotlin/com/nate/posedetection/App.kt
··· 359 359 }, 360 360 objectModel = generalModel, 361 361 modifier = Modifier.weight(1f), 362 + focusArea = Rect(0f,0f,0.1f,1f), 362 363 frontCamera = false, 363 364 recordingId = recordingId, 364 365 onVideoSaved = {id,url -> path = url },