How to Use Images in Jetpack Compose?

Jetpack Compose Image

In this article, we will learn how to use images in Android Jetpack Compose with the help of examples.

Prerequisites:

Let’s start coding.

First, create an empty Jetpack Compose project and open MainActivity. Next, create a MyUI() composable and call it from the onCreate() method.

// if you are coding with me, add the following imports
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.BlurredEdgeTreatment
import androidx.compose.ui.draw.blur
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourProjectNameTheme(darkTheme = false) {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Column(
                        modifier = Modifier.fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        MyUI()
                    }
                }
            }
        }
    }
}

@Composable
fun MyUI() {

}

We will write our code in the MyUI().

Next, download the dog image. Select 640×462 size while downloading it. Change its name to dog.jpg and put it in the res > drawable folder.

Jetpack Compose provides Image API. Start typing Image and select the one with the painter parameter. We will talk about the other overloads in a moment.

jetpack compose image painter api

It looks like this:

@Composable
fun Image(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
)

painter – It is to draw the image on the screen.

contentDescription – It is a text that describes the image. Accessibility services (like screen readers) use this text. If you don’t want this behavior, pass null.

modifier – To modify the layout.

alignment – It aligns the image in the given bounds.

contentScale – It is used to scale the image. Look at the official docs for the visual guide.

alpha – Opacity of the image. 0f represents fully transparent and 1f represents fully opaque.

colorFilter – It modifies the individual pixels of the image.

Simple Image Example:

For a simple image, painter and contentDescription are mandatory. We can get the Painter object from the painterResource() method.

@Composable
fun painterResource(@DrawableRes id: Int): Painter

Here, id represents the drawable resource id (an integer) of the image.

painterResource currently supports the following drawable types:

  • AnimatedVectorDrawable
  • BitmapDrawable (PNG, JPG, WEBP)
  • ColorDrawable
  • VectorDrawable

Example:

@Composable
fun MyUI() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = "Dog Image"
    )
}

Output:

Simple Image Example in Jetpack Compose

Image Button:

We can create an image button by setting the clickable modifier on the Image composable.

@Composable
fun MyUI() {
    val contextForToast = LocalContext.current.applicationContext

    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = "Dog Image",
        modifier = Modifier.clickable {
            Toast.makeText(contextForToast, "Click!", Toast.LENGTH_SHORT).show()
        }
    )
}

Output:

Image Button

Circular Image:

To make an image fit into a shape, use the built-in clip modifier. Jetpack Compose offers several shape APIs. We use the CircleShape to create a circle effect.

@Composable
fun MyUI() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = null,
        modifier = Modifier
            .size(160.dp)
            .clip(CircleShape)
            .border(width = 2.dp, color = Color.Green, shape = CircleShape),
        contentScale = ContentScale.Crop
    )
}

Output:

Circular Image

Note: Instead of CircleShape, we can also pass RoundedCornerShape(percent = 50).

Image with Custom Aspect Ratio:

We can set a custom aspect ratio using the modifier’s aspectRatio() method.

@Composable
fun MyUI() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = null,
        modifier = Modifier.aspectRatio(16f / 9f)
    )
}

Output:

custom aspect ratio

Image with Blur Effect:

Jetpack Compose provides blur modifier. It looks like this:

@Stable
fun Modifier.blur(
    radiusX: Dp,
    radiusY: Dp,
    edgeTreatment: BlurredEdgeTreatment = BlurredEdgeTreatment.Rectangle,
): Modifier

radiusX – Radius of the blur along the x axis.

radiusY – Radius of the blur along the y axis.

edgeTreatment – It decides how to render pixels outside of bounds of the image.

There are two options for edgeTreatment:

1. BlurredEdgeTreatment(shape) – It doesn’t blur the pixels outside the bounds of the image. As a result, the edges of the image appear sharp.

2. BlurredEdgeTreatment.Unbounded – It is used for blurring pixels outside the bounds of the image. As a result, the edges of the image appear blurred.

Examples:

Using BlurredEdgeTreatment(shape):

@Composable
fun MyUI() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = null,
        modifier = Modifier
            .size(size = 160.dp)
            .blur(
                radiusX = 10.dp,
                radiusY = 10.dp,
                edgeTreatment = BlurredEdgeTreatment(shape = RoundedCornerShape(percent = 5))
            ),
        contentScale = ContentScale.Crop
    )
}

Output:

Blur image shape

Using BlurredEdgeTreatment.Unbounded:

@Composable
fun MyUI() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = null,
        modifier = Modifier
            .size(size = 160.dp)
            .blur(
                radiusX = 10.dp,
                radiusY = 10.dp,
                edgeTreatment = BlurredEdgeTreatment.Unbounded
            ),
        contentScale = ContentScale.Crop
    )
}

Output:

blur image unbounded

Note: The blur effect is only supported on Android 12 and above. If you use this Modifier on older versions, it results in no action.

Don’t worry. I found the following two libraries that support the blur effect on all Android versions:

  1. Cloudy – github.com/skydoves/Cloudy
  2. xBlur – github.com/x3rocode/xblur-compose/tree/main

Loading Image from a URL:

We can use the Coil library for loading images from a URL. First, add the internet permission in the AndroidManifest file.

<?xml version="1.0" encoding="utf-8"?>
<manifest>
 ...
    <uses-permission android:name="android.permission.INTERNET" />
 ...
</manifest>

Next, add the following imports in the MainActivity:

import coil.compose.rememberAsyncImagePainter
import coil.compose.rememberImagePainter

Coil provides rememberAsyncImagePainter() method to load an image from a URL.

Example:

@Composable
fun MyUI() {
    val asyncPainter =
        rememberAsyncImagePainter("https://semicolonspace.com/wp-content/uploads/2023/02/forest.jpg")

    Image(
        painter = asyncPainter,
        contentDescription = null
    )
}

Output:

Loading Image from URL

Image composable comes with two additional overloads, one that includes an imageVector parameter and another with a bitmap parameter. Let’s look at them.

Image() with imageVector parameter:

It helps us to draw image vectors.

@Composable
@NonRestartableComposable
fun Image(
    imageVector: ImageVector,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
)

Example:

@Composable
fun MyUI() {
    Image(
        imageVector = Icons.Filled.Search,
        contentDescription = null,
        modifier = Modifier.size(size = 100.dp)
    )
}

Output:

Image with imageVector parameter

Related: Icons in Jetpack Compose

Image() with bitmap Parameter:

It helps us to draw bitmap objects.

@Composable
@NonRestartableComposable
fun Image(
    bitmap: ImageBitmap,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null,
    filterQuality: FilterQuality = DefaultFilterQuality
)

There is an extra parameter called filterQuality. It is the sampling algorithm applied to the bitmap when it is scaled and drawn into the destination.

Example:

@Composable
fun MyUI() {
    val context = LocalContext.current
    val bitmap = ContextCompat.getDrawable(context, R.drawable.dog)?.toBitmap()
        ?.asImageBitmap()!!

    Image(
        bitmap = bitmap,
        contentDescription = null,
        modifier = Modifier.size(size = 100.dp)
    )
}

Output:

Image bitmap in Jetpack Compose

This is all about displaying Images in Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.

Related Articles:

Leave a Comment