android 在编写中,如何在线圈从URL加载图像后访问可绘制对象

amrnrhlw  于 2022-12-21  发布在  Android
关注(0)|答案(4)|浏览(137)

我正在使用accompanist-coil:0.12.0。我想从一个url加载图像,然后将可绘制对象传递给一个方法。我正在使用这个:

val painter = rememberCoilPainter(
        request = ImageRequest.Builder(LocalContext.current)
            .data(imageUrl)
            .target {
                viewModel.calcDominantColor(it) { color ->
                    dominantColor = color
                }
            }
            .build(),
        fadeIn = true
    )

然后像这样把painter传递给Image

Image(
   painter = painter,
   contentDescription = "Some Image",
)

加载映像时没有任何问题,但从未调用方法calcDominantColor
我是不是做错了?

    • 更新日期:**

我可以在requestBuilder中使用Transformation调用该方法,但我不确定这是否是应该做的,因为我实际上并没有 * 转换 * Bitmap本身:

val painter = rememberCoilPainter(
        request = entry.imageUrl,
        requestBuilder = {
            transformations(
                object: Transformation{
                    override fun key(): String {
                        return entry.imageUrl
                    }
                    override suspend fun transform(
                        pool: BitmapPool,
                        input: Bitmap,
                        size: Size
                    ): Bitmap {
                        viewModel.calcDominantColor(input) { color ->
                            dominantColor = color
                        }
                        return input
                    }
                }
            )
        }
    )

这在第一次使用时效果很好,但是当可组合程序重新组合时,转换从缓存中返回,我的方法不运行。

rjjhvcjd

rjjhvcjd1#

我认为您希望使用LaunchedEffect沿着ImageLoader来访问加载器结果中的位图。

val context = LocalContext.current

    val imageLoader = ImageLoader(context)

    val request = ImageRequest.Builder(context)
        .transformations(RoundedCornersTransformation(12.dp.value))
        .data(imageUrl)
        .build()

    val imagePainter = rememberCoilPainter(
        request = request,
        imageLoader = imageLoader
    )

    LaunchedEffect(key1 = imagePainter) {
        launch {
            val result = (imageLoader.execute(request) as SuccessResult).drawable
            val bitmap = (result as BitmapDrawable).bitmap
            val vibrant = Palette.from(bitmap)
                .generate()
                .getVibrantColor(defaultColor)
            // do something with vibrant color
        }
    }
aemubtdh

aemubtdh2#

我建议使用新的coil-compose库,只需复制以下内容并将其添加到app build.gradle文件即可:

implementation "io.coil-kt:coil-compose:1.4.0"

我也在遵循教程,在这一点上卡住了。我会建议复制并粘贴以下代码:

Column {
            val painter = rememberImagePainter(
                data = entry.imageUrl
            )
            val painterState = painter.state
            Image(
                painter = painter,
                contentDescription = entry.pokemonName,
                modifier = Modifier
                    .size(120.dp)
                    .align(CenterHorizontally),
            )
            if (painterState is ImagePainter.State.Loading) {
                CircularProgressIndicator(
                    color = MaterialTheme.colors.primary,
                    modifier = Modifier
                        .scale(0.5f)
                        .align(CenterHorizontally)
                )
            }
            else if (painterState is ImagePainter.State.Success) {
                LaunchedEffect(key1 = painter) {
                    launch {
                        val image = painter.imageLoader.execute(painter.request).drawable
                        viewModel.calcDominantColor(image!!) {
                            dominantColor = it
                        }
                    }
                }
            }
            Text(
                text = entry.pokemonName,
                fontFamily = RobotoCondensed,
                textAlign = TextAlign.Center,
                modifier = Modifier.fillMaxWidth()
            )
        }
x8goxv8g

x8goxv8g3#

将“异步图像”替换为“可绘制的异步图像”:

@Composable
fun AsyncImageWithDrawable(
    model: Any?,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    placeholderResId: Int? = null,
    errorResId: Int? = null,
    fallbackResId: Int? = errorResId,
    contentScale: ContentScale,
    onDrawableLoad: (Drawable?) -> Unit) {

    val painter = rememberAsyncImagePainter(
        ImageRequest.Builder(LocalContext.current).data(data = model)
            .apply(block = fun ImageRequest.Builder.() {
                crossfade(true)
                placeholderResId?.let { placeholder(it) }
                errorResId?.let { error(it) }
                fallbackResId?.let { fallback(it) }
                allowHardware(false)
            }).build()
    )

    val state = painter.state

    Image(
        painter = painter,
        contentDescription = contentDescription,
        modifier = modifier,
        contentScale = contentScale
 )

    when (state) {
        is AsyncImagePainter.State.Success -> {
            LaunchedEffect(key1 = painter) {
                launch {
                    val drawable: Drawable? = 
            painter.imageLoader.execute(painter.request).drawable
            onDrawableLoad(drawable)
                }
            }
        }
        else -> {}
    }
}

我已经创建了这个可组合的灵感来自@Aknk答案和线圈源代码。
提示:您可以使用这个Composable从URL加载和渲染您的图像,并通过返回的Drawable获得您的图像Palette

ercv8c1e

ercv8c1e4#

您可以使用**onSuccess**回调函数获取可绘制对象:

AsyncImage(
    model = url,
    contentDescription = null,
    onSuccess = { success ->
        val drawable = success.result.drawable
    }
)

您也可以对rememberAsyncImagePainter使用相同的方法。

相关问题