Base64
Bitmap
ImageView
Android Development
Image Conversion

How to convert a Base64 string into a Bitmap image to show it in a ImageView?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Displaying a Base64-encoded image in an Android ImageView is a two-step process: decode the string into bytes, then decode those bytes into a Bitmap. The basic code is short, but production-quality handling needs to account for malformed input, optional data-URI prefixes, and memory usage for large images.

The Basic Conversion

If you already have a plain Base64 string for a PNG or JPEG, the core logic looks like this in Kotlin:

kotlin
1import android.graphics.Bitmap
2import android.graphics.BitmapFactory
3import android.util.Base64
4
5fun decodeBase64ToBitmap(base64: String): Bitmap? {
6    val bytes = Base64.decode(base64, Base64.DEFAULT)
7    return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
8}

Then assign the result to an ImageView:

kotlin
val bitmap = decodeBase64ToBitmap(base64String)
imageView.setImageBitmap(bitmap)

That is the essential conversion.

Handling Data URI Prefixes

Many APIs and web-originated payloads include a prefix such as:

text
data:image/png;base64,...

Android's Base64.decode() cannot use that whole string directly. Strip the metadata first:

kotlin
fun cleanBase64(input: String): String {
    return input.substringAfter("base64,", input)
}

Then decode:

kotlin
val cleaned = cleanBase64(base64String)
val bitmap = decodeBase64ToBitmap(cleaned)
imageView.setImageBitmap(bitmap)

Without this cleanup step, decoding often fails with IllegalArgumentException.

A Safer Utility Function

For app code, it is better to wrap the operation in a helper that handles malformed strings gracefully.

kotlin
1import android.graphics.Bitmap
2import android.graphics.BitmapFactory
3import android.util.Base64
4
5fun base64ToBitmap(input: String): Bitmap? {
6    return try {
7        val cleaned = input.substringAfter("base64,", input)
8        val bytes = Base64.decode(cleaned, Base64.DEFAULT)
9        BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
10    } catch (e: IllegalArgumentException) {
11        null
12    }
13}

Usage:

kotlin
1val bitmap = base64ToBitmap(base64String)
2
3if (bitmap != null) {
4    imageView.setImageBitmap(bitmap)
5} else {
6    imageView.setImageResource(R.drawable.image_error)
7}

This avoids crashing the UI if the incoming data is not valid Base64.

Large Images and Memory

The real problem often is not decoding. It is decoding too much. If the Base64 payload represents a very large image, converting it directly into a full bitmap can consume a lot of memory and trigger OutOfMemoryError.

For oversized images, decode with sampling:

kotlin
1fun decodeSampledBitmap(bytes: ByteArray, sampleSize: Int): Bitmap? {
2    val options = BitmapFactory.Options().apply {
3        inSampleSize = sampleSize
4    }
5    return BitmapFactory.decodeByteArray(bytes, 0, bytes.size, options)
6}

This reduces memory by loading a smaller bitmap. It is especially useful for thumbnails or list items.

Background Threading

Base64 decoding plus bitmap creation can be expensive enough to cause UI jank if done repeatedly on the main thread. In modern Android code, move the work to a coroutine on a background dispatcher and return the result to the UI thread.

The key idea is simple: decode off the main thread, then assign the bitmap on the main thread.

Common Pitfalls

The most common mistake is feeding a full data URI into Base64.decode() without stripping the prefix. The conversion then fails even though the underlying image bytes are fine.

Another mistake is assuming every Base64 string is an image. Some payloads are empty, truncated, or encoded with unexpected flags.

Large images are another frequent source of trouble. Decoding a huge bitmap directly into memory can crash the app or make scrolling choppy.

Finally, if you load many images or remote image data frequently, consider whether a full-featured image-loading library is a better fit than hand-written Base64 decoding in UI code.

Summary

  • Decode Base64 into bytes, then decode the bytes into a Bitmap.
  • Strip any data:image/...;base64, prefix before decoding.
  • Return null or a fallback image for malformed input instead of crashing.
  • Use sampled decoding for large images to reduce memory pressure.
  • Move heavy decoding work off the main thread for smoother UI behavior.

Course illustration
Course illustration

All Rights Reserved.