0

I'm trying to apply a tint colour using Compose, Coil 2.4 with SVG extension, but it does not really work.

SubcomposeAsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data("https://www.svgrepo.com/show/43967/colours-samples.svg")
        .decoderFactory(SvgDecoder.Factory())
        .crossfade(true)
        .build(),
    contentDescription = "",
    colorFilter = ColorFilter.tint(Color.Red)
) {
    when (painter.state) {
        is AsyncImagePainter.State.Error -> ImageErrorContent()
        is AsyncImagePainter.State.Loading -> ImageLoadingContent()
        else -> Image(
            painter = painter,
            contentDescription = contentDescription,
        )
    }
}

SubcomposeAsyncImage is from Coil.

I am using SubcomposeAsyncImage instead of other solutions such as coil.compose.AsyncImage or androidx.compose.material.Icon with Coil's image request builder because I need to override the loading and error states with different Composables.

This is a sample I made to showcase the issue. My expectation is that the downloaded image (black-outlined SVG) should be red. I tried with different blend modes but that didn't work.

is there any way to achieve the desired tinting with SVGs coming from a URL? It has worked fine with similar SVGs that were converted into a drawable using Compose's Icon/Image composables.

Thanks for the answers in advance :)

Peter Szucs
  • 1,116
  • 9
  • 18

1 Answers1

1

Edit:

Since you are using Image() for showing the final data from async image,you need to add colorFilter to Image composable instead of SubcomposeAsyncImage

Sample implementation with colorFilter:

SubcomposeAsyncImage(
        model = ImageRequest.Builder(LocalContext.current)
            .data("https://www.svgrepo.com/show/43967/colours-samples.svg")
            .decoderFactory(SvgDecoder.Factory())
            .build(),
        modifier = Modifier
            .padding(horizontal = 16.dp, vertical = 4.dp)
            .size(50.dp),
        contentDescription = null
    ){
        when(painter.state){
            is AsyncImagePainter.State.Error -> {
                // Error content
            }
            is AsyncImagePainter.State.Loading -> CircularProgressIndicator()
            else -> Image(
                painter = painter,
                contentDescription = contentDescription,
                colorFilter = ColorFilter.tint(Color.Red)
            )
        }
    }

Result with colorFilter:

enter image description here

Megh
  • 831
  • 2
  • 12
  • Hey, thanks for the answer! I've edited the question but place it here as well, SubcomposeAsyncImage is from Coil: https://github.com/coil-kt/coil/blob/main/coil-compose-base/src/main/java/coil/compose/SubcomposeAsyncImage.kt – Peter Szucs Jul 11 '23 at 06:33
  • I am using Subcompose AsyncImage as I need the state to show different composables for error and loading states. – Peter Szucs Jul 11 '23 at 06:34
  • Thanks for the update! Please check updated answer – Megh Jul 11 '23 at 06:49