7

How to load image from remote url in Kotlin Compose desktop?

in Android it use coli as official sample

@Composable
fun NetworkImage(
    url: String,
    modifier: Modifier = Modifier,
    contentScale: ContentScale = ContentScale.Crop,
    placeholderColor: Color? = MaterialTheme.colors.compositedOnSurface(0.2f)
) {
    CoilImage(
        data = url,
        modifier = modifier,
        contentScale = contentScale,
        loading = {
            if (placeholderColor != null) {
                Spacer(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(placeholderColor)
                )
            }
        }
    )
}

bu as desktop application, aar is not supported.

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
Thomas Liao
  • 215
  • 3
  • 12

4 Answers4

7

Use javax.imageio.ImageIO to load an image from network:

import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import org.jetbrains.skija.Image
import java.io.ByteArrayOutputStream
import java.net.HttpURLConnection
import java.net.URL
import javax.imageio.ImageIO

fun loadNetworkImage(link: String): ImageBitmap {
    val url = URL(link)
    val connection = url.openConnection() as HttpURLConnection
    connection.connect()

    val inputStream = connection.inputStream
    val bufferedImage = ImageIO.read(inputStream)

    val stream = ByteArrayOutputStream()
    ImageIO.write(bufferedImage, "png", stream)
    val byteArray = stream.toByteArray()

    return Image.makeFromEncoded(byteArray).asImageBitmap()
}

And then use it as:

Image(
    bitmap = loadNetworkImage("Your image link")
)
Saurabh Thorat
  • 18,131
  • 5
  • 53
  • 70
  • 1
    actually , I finding the solution to act like Glide or Coli for fetching, decoding, and displaying an Image which from a remote url, and with the state of pause, resume, etc. but thx @Saurabh Thorat – Thomas Liao Mar 04 '21 at 02:28
  • Note, this also can work for files not from a URL, since it uses bytes to pipe through `Image.makeFromEncoded()`. In my own context, I was getting a file from JFileChooser, and used `org.jetbrains.skija.Image` in this way. – Christian Gruber May 28 '21 at 19:09
3

A simple way I found was to use ktor to get the image as a byteArray and then use the Kotlin function makeFromEncoded to create a ImageBitmap which can then be used in a Composable Image

suspend fun loadPicture(url: String): ImageBitmap {
    val image = ktorHttpClient.use { client ->
        client.get<ByteArray>(url)
    }
    return Image.makeFromEncoded(image).asImageBitmap()
}

Then inside your composable

if (imageBitmap != null) {
    Image(bitmap = imageBitmap, "content description")
}
  • Nice. Thanks. I had to modify : with kotlin 1.8.20 compose 1.4.0 kto 2.2.4 ``` suspend fun loadPicture(url: String): ImageBitmap { val httpClient = HttpClient { install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true useAlternativeNames = false }) } } val image: ByteArray = httpClient.use { client -> client.get(url).body() } return Image.makeFromEncoded(image).toComposeImageBitmap() } ``` – Louis GRIGNON May 24 '23 at 09:35
0

Here's the approach I found.

import androidx.compose.ui.graphics.toComposeImageBitmap
import org.jetbrains.skia.Image
import java.net.URL

fun loadImage(url: String) =
    Image.makeFromEncoded(URL(url).readBytes())
        .toComposeImageBitmap()
Shaun Wild
  • 1,237
  • 3
  • 17
  • 34
0

this one worked for me.

fun loadImage(url: String): ImageBitmap {
    return ImageIO.read(URL(url)).toComposeImageBitmap()
}

You can then use

Image(
    bitmap = loadImage(imageUrl),
    contentDescription = null
)
sayang_android
  • 47
  • 1
  • 1
  • 6