Reza
Reza

Reputation: 4773

How can I display a Base64 encoded image in Android using Coil?

I'm attempting to display a PNG image encoded as a Base64 string in an Android app using Coil, but nothing shows up. My Base64 string starts like this: data:image/png;base64,iVBORw0KGgo... and I'm trying to decode and display using Coil.

Here's the code snippet:

val base64ImageString = "data:image/png;base64,iVBORw0KGgo..." // Your Base64 string here    
val imageLoader = ImageLoader(context)
val request = ImageRequest.Builder(context)
    .data(base64ImageString)
    .target(imageView)
    .build()

imageLoader.enqueue(request)

Upvotes: 1

Views: 1589

Answers (2)

mxkmn
mxkmn

Reputation: 543

In addition to @Reza's reply. In Compose, you can just pass ByteArray in model:

import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi

/*private const*/ val BASE64_SUBSTRING = "base64,"

@OptIn(ExperimentalEncodingApi::class)
val base64ImageByteArray = Base64.decode(base64ImageString.substringAfter(BASE64_SUBSTRING))

AsyncImage(
    model = base64ImageByteArray,
    contentDescription = null,
    placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceContainer),
    error = ColorPainter(MaterialTheme.colorScheme.surfaceDim),
    contentScale = ContentScale.Crop,
)

Upvotes: 1

Reza
Reza

Reputation: 4773

I discovered the issue was due to not properly stripping the data:image/png;base64, prefix before decoding the Base64 string. Here’s the corrected approach:

// Kotlin code snippet
val base64ImageStringWithPrefix = "data:image/png;base64,iVBORw0KGgo..." // Full Base64 string
val base64ImageString = base64ImageStringWithPrefix.substringAfter("base64,")

val imageByteArray = Base64.decode(base64ImageString, Base64.DEFAULT)

// Use Coil to load the byte array into the ImageView
val imageLoader = ImageLoader(context)
val request = ImageRequest.Builder(context)
    .data(imageByteArray)
    .target(imageView)
    .listener(
        onError = { _, throwable ->
            // Log or handle the error
            throwable.printStackTrace()
        }
    )
    .build()

imageLoader.enqueue(request)

Upvotes: 5

Related Questions