In today’s tutorial, we learn how to use KMP to load images from HTTP URLs using the CoilImage library for both Android and iOS. Displaying images from HTTP or HTTPS URLs is essential for every mobile and web application because you cannot store all the application’s images in in-app storage. When working with API, a lot of dynamic data, including images, comes from the server. So, we have to load all of these images from HTTP and HTTPS URLs in our app.
KMP Load Image From HTTP URL in Compose Multiplatform
We are using the CoilImage GitHub library to load images. The library’s page mentions other libraries for loading images, such as GlideImage and Fresco. You can visit its GitHub page HERE.
Setup CoilImage in KMP project:
1. Open your KMP compose multiplatform composeApp -> build.gradle.kt app level file.
2. Paste the CoilImage library in commonMain dependencies. I am using the latest version as of the current date, but if you read this tutorial later, you can find the latest version HERE.
1 |
implementation("com.github.skydoves:landscapist-coil3:2.4.4") |
3. Now, we have to set Androd compiled SDK as 35. You can skip this step if you have already used the compiled SDK as 35. To set up, please open gradle -> libs.versions.tool file. And set android-compileSdk as 35.
Now, SYNC and rebuild your project. Then, we are ready to start the coding.
Error Image: I have designed a custom 404 image not found in Photoshop. You can download and use this image in your project without my content. It is free for everyone. After downloading the image, put it in the composeApp -> commonMain -> composeResource -> drawable folder. After placing the image, rebuild the project. Without rebuilding the project, your image will not be visible as an import.
CoilImage Integration in code in KMP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
@Composable fun ImageFromUrl() { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { CoilImage( modifier = Modifier.size(300.dp) .clip(RoundedCornerShape(size = 12.dp)), imageModel = { "https://www.kotlinguide.com/wp-content/uploads/2024/12/demo_image.png" }, imageOptions = ImageOptions( contentScale = ContentScale.Fit, alignment = Alignment.Center ), loading = { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { CircularProgressIndicator( modifier = Modifier.size(28.dp) ) } }, failure = { Box( modifier = Modifier.fillMaxSize() ) { Image( modifier = Modifier.fillMaxSize(), painter = painterResource(Res.drawable.image_not_found), contentDescription = "404 Image Not Found", contentScale = ContentScale.FillBounds ) } } ) } } |
Code explanation:
- modifier = Modifier.size().clip(RoundedCornerShape()): Set the rounded HTTP image corner.
- imageModel: Pass the complete image URL here in double quotes as String.
- imageOptions: Set image alignment within the parent widget and set image scale type.
- loading: Show the Circular progress indicator while loading the image.
- Failure: Show a custom widget if the image is unavailable, 404 is not found, or something went wrong.
Complete source code for App.kt file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
package com.app.test import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import com.skydoves.landscapist.ImageOptions import com.skydoves.landscapist.coil3.CoilImage import org.jetbrains.compose.resources.painterResource import testapp.composeapp.generated.resources.Res import testapp.composeapp.generated.resources.image_not_found @Composable fun App() { MaterialTheme { Column( modifier = Modifier .fillMaxSize() .padding(8.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { ImageFromUrl() } } } @Composable fun ImageFromUrl() { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { CoilImage( modifier = Modifier.size(300.dp) .clip(RoundedCornerShape(size = 12.dp)), imageModel = { "https://www.kotlinguide.com/wp-content/uploads/2024/12/demo_image.png" }, imageOptions = ImageOptions( contentScale = ContentScale.Fit, alignment = Alignment.Center ), loading = { Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { CircularProgressIndicator( modifier = Modifier.size(28.dp) ) } }, failure = { Box( modifier = Modifier.fillMaxSize() ) { Image( modifier = Modifier.fillMaxSize(), painter = painterResource(Res.drawable.image_not_found), contentDescription = "404 Image Not Found", contentScale = ContentScale.FillBounds ) } } ) } } |
Screenshots: