Avoid calling Bitmap.asImageBitmap() too often
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user