Avoid calling Bitmap.asImageBitmap() too often

This commit is contained in:
Pierre-Yves Nicolas
2025-06-26 08:07:12 +02:00
parent b9cb072be8
commit d28ade8518

View File

@@ -61,6 +61,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.boundsInWindow
@@ -182,67 +183,68 @@ private fun CameraScreenScaffold(
) )
} }
} }
CapturedImage(cameraUiState, thumbnailCoords) cameraUiState.captureState.processedImage?.let {
image -> CapturedImage(image.asImageBitmap(), thumbnailCoords)
}
} }
} }
@Composable @Composable
private fun CapturedImage(cameraUiState: CameraUiState, thumbnailCoords: MutableState<Offset>) { private fun CapturedImage(image: ImageBitmap, thumbnailCoords: MutableState<Offset>) {
cameraUiState.captureState.processedImage?.let { image -> Surface(
Surface( color = Color.Black.copy(alpha = 0.3f),
color = Color.Black.copy(alpha = 0.3f), modifier = Modifier.fillMaxSize(),
modifier = Modifier.fillMaxSize(), ) {}
) {}
var isAnimating by remember { mutableStateOf(false) } var isAnimating by remember { mutableStateOf(false) }
LaunchedEffect(image) { LaunchedEffect(image) {
delay(CAPTURED_IMAGE_DISPLAY_DURATION - ANIMATION_DURATION) delay(CAPTURED_IMAGE_DISPLAY_DURATION - ANIMATION_DURATION)
isAnimating = true isAnimating = true
} }
val transition = updateTransition(targetState = isAnimating, label = "captureAnimation") val transition = updateTransition(targetState = isAnimating, label = "captureAnimation")
val density = LocalDensity.current val density = LocalDensity.current
var targetOffsetX by remember { mutableFloatStateOf(0f) } var targetOffsetX by remember { mutableFloatStateOf(0f) }
var targetOffsetY by remember { mutableFloatStateOf(0f) } var targetOffsetY by remember { mutableFloatStateOf(0f) }
val offsetX by transition.animateFloat( val offsetX by transition.animateFloat(
transitionSpec = { tween(durationMillis = ANIMATION_DURATION) }, transitionSpec = { tween(durationMillis = ANIMATION_DURATION) },
label = "offsetX" label = "offsetX"
) { if (it) targetOffsetX else 0f } ) { if (it) targetOffsetX else 0f }
val offsetY by transition.animateFloat( val offsetY by transition.animateFloat(
transitionSpec = { tween(durationMillis = ANIMATION_DURATION) }, transitionSpec = { tween(durationMillis = ANIMATION_DURATION) },
label = "offsetY" label = "offsetY"
) { if (it) targetOffsetY else 0f } ) { if (it) targetOffsetY else 0f }
val scale by transition.animateFloat( val scale by transition.animateFloat(
transitionSpec = { tween(durationMillis = ANIMATION_DURATION) }, transitionSpec = { tween(durationMillis = ANIMATION_DURATION) },
label = "scale" label = "scale"
) { if (it) 0.3f else 1f } ) { if (it) 0.3f else 1f }
Box (modifier = Modifier Box (contentAlignment = Alignment.BottomStart,
.fillMaxHeight(0.8f) modifier = Modifier
.onGloballyPositioned { coordinates -> .fillMaxHeight(0.8f)
val bounds = coordinates.boundsInWindow() .onGloballyPositioned { coordinates ->
val centerX = bounds.left + bounds.width / 2 val bounds = coordinates.boundsInWindow()
val centerY = bounds.top + bounds.height / 2 val centerX = bounds.left + bounds.width / 2
with(density) { val centerY = bounds.top + bounds.height / 2
targetOffsetX = thumbnailCoords.value.x - centerX with(density) {
targetOffsetY = thumbnailCoords.value.y - centerY targetOffsetX = thumbnailCoords.value.x - centerX
} targetOffsetY = thumbnailCoords.value.y - centerY
} }
) {
Image(
bitmap = image.asImageBitmap(),
contentDescription = null,
modifier = Modifier
.fillMaxSize()
.padding(24.dp)
.graphicsLayer {
translationX = offsetX
translationY = offsetY
scaleX = scale
scaleY = scale
}
)
} }
) {
Image(
bitmap = image,
contentDescription = null,
modifier = Modifier
.fillMaxSize()
.padding(24.dp)
.graphicsLayer {
translationX = offsetX
translationY = offsetY
scaleX = scale
scaleY = scale
}
)
} }
} }