在 jetpack compose 中更新图像中的位图
Update bitmap in Image in jetpack compose
任务:我在设置网格后尝试模糊视图,其中的单元格具有不同的颜色(在 [=55= 中效果很好) ] SDK 31+)
情况:由于在android SDK 31以下无法使用compose中的模糊,(我正在使用Renderscript来模糊捕获的视图位图)
问题:我不确定处理完成后如何更新图像中的位图或add/remove合成中的图像
到目前为止我做了什么:
模糊 android SDK 31+
@Composable
fun PlaceHolder(viewModel: PlaceHolderViewModel) {
val viewState by rememberFlowWithLifecycle(viewModel.state)
.collectAsState(initial = PlaceHolderViewState.Empty)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
PlaceHolderBlurBelowSDK31(viewState = viewState)
} else {
PlaceHolder(viewState = viewState)
}
}
/**
* blur for compose is only available for android 31 and above devices.
*/
@Composable
private fun PlaceHolder(viewState: PlaceHolderViewState) = Box(
modifier = Modifier.blur(radius = 60.dp)
) {
PlaceHolderGrid(viewState = viewState)
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun PlaceHolderGrid(viewState: PlaceHolderViewState) {
val size = max(viewState.placeHolderInfo.colors.size, 3)
val cellHeight = viewState.placeHolderInfo.maxHeight / (size / 3)
LazyVerticalGrid(cells = GridCells.Fixed(3)) {
itemsIndexed(items = viewState.placeHolderInfo.colors) { i: Int, color: String ->
Box(
modifier = Modifier
.fillMaxWidth()
.height(cellHeight.dp)
.background(color = color.getColor())
)
}
}
}
这是我正在为 android 31 以下的 SDK 尝试的
@Composable
fun PlaceHolderBlurBelowSDK31(viewState: PlaceHolderViewState) {
CaptureBitmap(content = {
PlaceHolderGrid(viewState = viewState)
}, laidOut = { bitmap ->
if (bitmap != null && bitmap.width != 0 && bitmap.height != 0) {
val painter = rememberAsyncImagePainter(ImageRequest.Builder(LocalContext.current)
.data(data = bitmap)
.apply(
block = {
scale(Scale.FILL)
}
).build())
Logger.e("placeholder", "Image - " + System.currentTimeMillis())
Image(
painter = painter,
modifier = Modifier
.wrapContentSize()
.padding(16.dp),
colorFilter = ColorFilter.tint(Color.Red),
contentScale = ContentScale.Crop,
contentDescription = "logo"
)
}
})
}
@Composable
fun CaptureBitmap(
content: @Composable () -> Unit,
laidOut: @Composable (Bitmap?) -> Unit
) {
val context = LocalContext.current
/**
* ComposeView that would take composable as its content
* Kept in remember so recomposition doesn't re-initialize it
**/
val composeView = remember { ComposeView(context) }
/**
* Callback function which could get latest image bitmap
**/
fun captureBitmap(): Bitmap? {
return try {
composeView.drawToBitmap()
} catch (e: Exception) {
null
}
}
/** Use Native View inside Composable **/
AndroidView(modifier = Modifier
.onGloballyPositioned {
Logger.e("placeholder", "onGloballyPositioned - " + System.currentTimeMillis())
laidOut.invoke(captureBitmap())
},
factory = {
ComposeView(it).apply {
setContent {
Logger.e("placeholder", "setContent - " + System.currentTimeMillis())
content.invoke()
}
}
}
)
}
需要位图方面的帮助才能更新图像。我知道它需要从 @Composable 作用域或函数中调用。
laidOut.invoke(captureBitmap())
我试过了
val bitmap: MutableState<Bitmap?> = mutableStateOf(null)
bitmap.value = captureBitmap()
但是,我没有取得任何进展。
请帮忙。
网格:
模糊:
在 Compose 中,当您需要更新视图时,任何此类情况都可以通过状态解决。创建可选位图类型的可变状态,更新它并显示它不是 null
:
fun captureBitmap(): Bitmap? {
return try {
composeView.drawToBitmap()
} catch (e: Exception) {
null
}
}
val (bitmap, updateBitmap) = remember { mutableStateOf<Bitmap?>(null) }
/** Use Native View inside Composable **/
AndroidView(modifier = Modifier
.onGloballyPositioned {
Logger.e("placeholder", "onGloballyPositioned - " + System.currentTimeMillis())
updateBitmap(captureBitmap())
},
// ..
)
if (bitmap != null) {
laidOut(bitmap)
}
我建议您查看 Compose documentation, including this youtube video 中的状态,它解释了基本原理。
任务:我在设置网格后尝试模糊视图,其中的单元格具有不同的颜色(在 [=55= 中效果很好) ] SDK 31+)
情况:由于在android SDK 31以下无法使用compose中的模糊,(我正在使用Renderscript来模糊捕获的视图位图)
问题:我不确定处理完成后如何更新图像中的位图或add/remove合成中的图像
到目前为止我做了什么:
模糊 android SDK 31+
@Composable
fun PlaceHolder(viewModel: PlaceHolderViewModel) {
val viewState by rememberFlowWithLifecycle(viewModel.state)
.collectAsState(initial = PlaceHolderViewState.Empty)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
PlaceHolderBlurBelowSDK31(viewState = viewState)
} else {
PlaceHolder(viewState = viewState)
}
}
/**
* blur for compose is only available for android 31 and above devices.
*/
@Composable
private fun PlaceHolder(viewState: PlaceHolderViewState) = Box(
modifier = Modifier.blur(radius = 60.dp)
) {
PlaceHolderGrid(viewState = viewState)
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun PlaceHolderGrid(viewState: PlaceHolderViewState) {
val size = max(viewState.placeHolderInfo.colors.size, 3)
val cellHeight = viewState.placeHolderInfo.maxHeight / (size / 3)
LazyVerticalGrid(cells = GridCells.Fixed(3)) {
itemsIndexed(items = viewState.placeHolderInfo.colors) { i: Int, color: String ->
Box(
modifier = Modifier
.fillMaxWidth()
.height(cellHeight.dp)
.background(color = color.getColor())
)
}
}
}
这是我正在为 android 31 以下的 SDK 尝试的
@Composable
fun PlaceHolderBlurBelowSDK31(viewState: PlaceHolderViewState) {
CaptureBitmap(content = {
PlaceHolderGrid(viewState = viewState)
}, laidOut = { bitmap ->
if (bitmap != null && bitmap.width != 0 && bitmap.height != 0) {
val painter = rememberAsyncImagePainter(ImageRequest.Builder(LocalContext.current)
.data(data = bitmap)
.apply(
block = {
scale(Scale.FILL)
}
).build())
Logger.e("placeholder", "Image - " + System.currentTimeMillis())
Image(
painter = painter,
modifier = Modifier
.wrapContentSize()
.padding(16.dp),
colorFilter = ColorFilter.tint(Color.Red),
contentScale = ContentScale.Crop,
contentDescription = "logo"
)
}
})
}
@Composable
fun CaptureBitmap(
content: @Composable () -> Unit,
laidOut: @Composable (Bitmap?) -> Unit
) {
val context = LocalContext.current
/**
* ComposeView that would take composable as its content
* Kept in remember so recomposition doesn't re-initialize it
**/
val composeView = remember { ComposeView(context) }
/**
* Callback function which could get latest image bitmap
**/
fun captureBitmap(): Bitmap? {
return try {
composeView.drawToBitmap()
} catch (e: Exception) {
null
}
}
/** Use Native View inside Composable **/
AndroidView(modifier = Modifier
.onGloballyPositioned {
Logger.e("placeholder", "onGloballyPositioned - " + System.currentTimeMillis())
laidOut.invoke(captureBitmap())
},
factory = {
ComposeView(it).apply {
setContent {
Logger.e("placeholder", "setContent - " + System.currentTimeMillis())
content.invoke()
}
}
}
)
}
需要位图方面的帮助才能更新图像。我知道它需要从 @Composable 作用域或函数中调用。
laidOut.invoke(captureBitmap())
我试过了
val bitmap: MutableState<Bitmap?> = mutableStateOf(null)
bitmap.value = captureBitmap()
但是,我没有取得任何进展。 请帮忙。
网格:
模糊:
在 Compose 中,当您需要更新视图时,任何此类情况都可以通过状态解决。创建可选位图类型的可变状态,更新它并显示它不是 null
:
fun captureBitmap(): Bitmap? {
return try {
composeView.drawToBitmap()
} catch (e: Exception) {
null
}
}
val (bitmap, updateBitmap) = remember { mutableStateOf<Bitmap?>(null) }
/** Use Native View inside Composable **/
AndroidView(modifier = Modifier
.onGloballyPositioned {
Logger.e("placeholder", "onGloballyPositioned - " + System.currentTimeMillis())
updateBitmap(captureBitmap())
},
// ..
)
if (bitmap != null) {
laidOut(bitmap)
}
我建议您查看 Compose documentation, including this youtube video 中的状态,它解释了基本原理。