coil-kt / coil

Image loading for Android and Compose Multiplatform.
https://coil-kt.github.io/coil/
Apache License 2.0
10.84k stars 665 forks source link

Compose Multiplatform support #842

Closed tiwiz closed 1 month ago

tiwiz commented 3 years ago

Is your feature request related to a problem? Please describe. As an Android Developer, I would love to use Coil with Compose Desktop in the same way I use Coil for Compose on Android.

Describe the solution you'd like Ideally, it would be the best to have the same approach we have on Android, so that the knowledge can be reused.

Additional context I think it would be OK to link the image download scope to either a LaunchedEffect in a Composable, or just link it to the Application lifecycle.

rsktash commented 11 months ago

@colinrtwhite org.jetbrains.skia.svg.SVGDOM has "render" method which draws image to the canvas. But the new Image class(for non android targets) return Bitmap. So it's a bit difficult to write a decoder for svg

colinrtwhite commented 11 months ago

@rustamsmax Ah yep, I think the Image API is likely to change after the first alpha is released. Currently it's only built to support static images on non-Android platforms. For the moment, you could prerender the SVG to a bitmap since we know the output size (options.size) and return that from the Decoder.

@DRSchlaubi Great looks like we might be able to use Skiko for GIF images as well. Though, the Image API will need to be changed.

MohamedRejeb commented 11 months ago

I'm working on migrating coil-svg to multiplatform and it's almost done. You can follow the progress here: #1965

MohamedRejeb commented 11 months ago

I'm thinking of changing the Image API by an interface similar to Compose Painter, it can be called CoilPainter or just Painter and it has a size and an onDraw method. And in coil-compose-core this coil Painter is going to behave the same as Compose Painter, it's just a wrapper after all. With this change, we will be able to migrate coil-gif to multiplatform, and coil-svg in multiplatform will be more lightweight because we will draw the svg to the canvas directly, no need to create Bitmap and Image instances.

rsktash commented 11 months ago

@MohamedRejeb maybe best approach is to make it a sealed class? any time in the future we can add extra type

MohamedRejeb commented 11 months ago

Yes, it's possible, but for Compose Painter should cover all the cases. This change is only for non-Android targets which are all using Compose Multiplatform.

alekseyHunter commented 11 months ago

@colinrtwhite Hello! Can you please tell my, if there are any plans to support displaying local images?

colinrtwhite commented 11 months ago

Hi folks, I just published Coil 3.0.0-alpha01. I'd recommend using that version over the snapshots. Check out the WIP upgrade guide here.

I haven't merged wasm support yet as I'm still waiting for Ktor support. If you need wasm support I'd continue to depend on the snapshots, which use Ktor 3.0.0-wasm2.

nowiwr01w commented 11 months ago

@colinrtwhite it would be great if you'd publish a snapshot with 3.0.0-wasm2

rsktash commented 11 months ago

@colinrtwhite https://coil-kt.github.io/coil/upgrading_to_coil3 link is not working

image
DRSchlaubi commented 11 months ago

It's here

sonatard commented 11 months ago

Hi! We're having trouble finding coil3.compose. Are there any other changes needed to migrate to Coil 3?

e: file:///xxx/app/src/main/java/com/xxx/android/components/module/Image.kt:6:14 Unresolved reference: compose
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c0947d79f..9e013c1d4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1018,7 +1018,9 @@ dependencies {
-    implementation("io.coil-kt:coil-compose:2.3.0")
+    val coilVersion = "3.0.0-alpha01"
+    implementation("io.coil-kt.coil3:coil:$coilVersion")
+    implementation("io.coil-kt.coil3:coil-network:$coilVersion")

diff --git a/app/src/main/java/com/xxx/android/components/module/Image.kt b/app/src/main/java/com/xxx/android/components/module/Image.kt
index 3dde784eb..e2e45ca94 100644
--- a/app/src/main/java/com/xxx/android/components/module/Image.kt
+++ b/app/src/main/java/com/xxx/android/components/module/Image.kt
@@ -3,9 +3,9 @@ package com.xxx.android.components.module
-import coil.compose.AsyncImagePainter
-import coil.compose.SubcomposeAsyncImage
-import coil.compose.SubcomposeAsyncImageContent
+import coil3.compose.AsyncImagePainter
+import coil3.compose.SubcomposeAsyncImage
+import coil3.compose.SubcomposeAsyncImageContent

 @Composable
 fun Image(
colinrtwhite commented 11 months ago

@sonatard You need to add a dependency on Coil's Compose artifact:

implementation("io.coil-kt.coil3:coil-compose:3.0.0-alpha01")
sonatard commented 11 months ago

@colinrtwhite Thanks!! I successfully built it by adding a dependency.

sonatard commented 11 months ago

@colinrtwhite Thank you for your support with KMP!

Coil3 is now running, so here's my diff. I hope you find it useful.


diff --git a/app/build.gradle.kts b/app/build.gradle.kts
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1018,7 +1018,9 @@ dependencies {

-    implementation("io.coil-kt:coil-compose:2.3.0")
+    val coilVersion = "3.0.0-alpha01"
+    implementation("io.coil-kt.coil3:coil-compose:$coilVersion")
+    implementation("io.coil-kt.coil3:coil-network:$coilVersion")

diff --git a/app/src/main/java/com/xxx/android/components/Main.kt b/app/src/main/java/com/xxx/android/components/Main.kt
index 1bfe7a053..0aab82fa6 100644
--- a/app/src/main/java/com/xxx/android/components/Main.kt
+++ b/app/src/main/java/com/xxx/android/components/Main.kt
@@ -1,11 +1,25 @@
+import coil3.ImageLoader
+import coil3.annotation.ExperimentalCoilApi
+import coil3.compose.setSingletonImageLoaderFactory
+import coil3.fetch.NetworkFetcher

+@OptIn(ExperimentalCoilApi::class)
 @Composable
 fun Main(infra: Infra, initialUrl: String?) {
+    // Coil3
+    // https://coil-kt.github.io/coil/upgrading_to_coil3/#network-images
+    setSingletonImageLoaderFactory { context ->
+        ImageLoader.Builder(context)
+            .components {
+                add(NetworkFetcher.Factory())
+            }
+            .build()
+    }
diff --git a/app/src/main/java/com/xxx/android/components/module/Image.kt b/app/src/main/java/com/xxx/android/components/module/Image.kt
--- a/app/src/main/java/com/xxx/android/components/module/Image.kt
+++ b/app/src/main/java/com/xxx/android/components/module/Image.kt
-import coil.compose.AsyncImagePainter
-import coil.compose.SubcomposeAsyncImage
-import coil.compose.SubcomposeAsyncImageContent
+import coil3.compose.AsyncImagePainter
+import coil3.compose.SubcomposeAsyncImage
+import coil3.compose.SubcomposeAsyncImageContent

 @Composable
 fun Image(
Vaibhav2002 commented 10 months ago

VectorPainters when used in placeholder, does not pick the LocalContentColor and is always in black color Hence not being visible in dark mode

placeholder = rememberVectorPainter(Icons.Default.Domain),
colinrtwhite commented 10 months ago

@Vaibhav2002 Please file a separate issue for this

mainrs commented 10 months ago

Regarding gif support, there is an official UI elements from Jetbrains that can render GIFs: https://github.com/JetBrains/compose-multiplatform/tree/master/components/AnimatedImage

It is not part of compose core but an addon library. This could be used for at least the desktop variant.

mahramane commented 9 months ago

When will Wasm be supported?

colinrtwhite commented 9 months ago

@mahramane I'm waiting for Ktor to publish a version with wasm support to Maven Central. I'm hesitant to publish a separate version to Maven Central like 3.0.0-alpha04-wasm as it's possible Renovate and other automated update services will try to update to those instead of the standard alphas.

If you need wasm support today the snapshots support WASM via 3.0.0-SNAPSHOT.

19lmyers commented 9 months ago

@mahramane I'm waiting for Ktor to publish a version with wasm support to Maven Central. I'm hesitant to publish a separate version to Maven Central like 3.0.0-alpha04-wasm as it's possible Renovate and other automated update services will try to update to those instead of the standard alphas.

If you need wasm support today the snapshots support WASM via 3.0.0-SNAPSHOT.

Hello, I'm attempting to pull in the snapshot version for WASM, but for some reason Gradle gives me an error claiming that the snapshot io.coil-kt.coil3:coil-network-ktor-wasm-js:3.0.0-SNAPSHOT:20240215.162906-49 is using Ktor 2.3.8, which doesn't support WASM.

artemyto commented 9 months ago

Wasm support has been merged to Ktor. The next 3.0.0 beta release of Ktor should support Wasm.

AmeerAmjed commented 9 months ago

Any update??? I use Ktor version 3.0.0-wasm2 but can't install coil3, I'm try install mutli version but get error "3.0.0-alpha04-wasm" & "3.0.0-alpha04" which one support wasmjs.

Could not resolve all dependencies for configuration ':shared:jsCompileClasspath'. Could not find io.coil-kt.coil3:coil-compose:3.0.0-alpha04-wasm. Searched in the following locations:

colinrtwhite commented 9 months ago

@AmeerAmjed 3.0.0-alpha04-wasm isn't a valid version.

colinrtwhite commented 9 months ago

3.0.0-alpha05 adds support for wasmJs! I implemented a work-around so Ktor 3.0.0-wasm2 (which isn't available on mavenCentral) is only required for the wasmJs artifact. If you don't add the wasmJs target, Coil will depend on Ktor 2.3.8.

joreilly commented 8 months ago

@colinrtwhite I probably misunderstood something from above but getting following when depending on 3.0.0-alpha05....do I need to add some other maven repo to resolve?

Could not resolve all dependencies for wasmJsCompileClasspath.
> Could not find io.coil-kt:coil:3.0.0-alpha05.
  Searched in the following locations:
joreilly commented 8 months ago

ah, I did have wrong dependency....following works

implementation("io.coil-kt.coil3:coil-compose:3.0.0-alpha05")
joreilly commented 8 months ago

So, it's resolving but image isn't being displayed for some reason. I'll try to dig a bit deeper later but if you do want to try it's happening in Compose for Web client in following branch

https://github.com/joreilly/PeopleInSpace/tree/dependency_updates

This is code I have

                AsyncImage(
                    modifier = Modifier.size(240.dp),
                    model = personImageUrl,
                    contentDescription = person.name
                )
rsktash commented 8 months ago

@joreilly maybe we must pass string as Uri

romainbsl commented 8 months ago

@joreilly I had the same issue when migrating to coil3.

Network feature has been extracted from coil-core so you need to had a network dependency https://coil-kt.github.io/coil/upgrading_to_coil3/#network-images

Surely you need io.coil-kt.coil3:coil-network-ktor :D

joreilly commented 8 months ago

Thanks @romainbsl , it's working now!

Screenshot 2024-03-02 at 21 03 23
sunny7498 commented 8 months ago

Getting this error in compose for desktop

image

edit - Adding kotlinx-coroutines-swing fixed this

hakanai commented 8 months ago

Been trying for a while today to make a better replacement for this error dialog. Good grief... it's like JetBrains have never heard of SwingX.

DRSchlaubi commented 8 months ago

Getting this error in compose for desktop image

edit - Adding kotlinx-coroutines-swing fixed this

That's actually documented

Been trying for a while today to make a better replacement for this error dialog. Good grief... it's like JetBrains has never heard of SwingX.

I doubt that's very important to them, as this screen is not seen very often anyways and it's probably not worth adding another library, which is deprecated, just to render that error dialog differently, which you can change using LocalWindowExceptionHandlerFactory

hakanai commented 8 months ago

Yeah I'm not saying to haul in the whole library for an error dialog, but to imitate it with one written in Compose which looks exactly like it.

Editing just to add, I'm seeing it on average around every 2~5 minutes while doing dev , so I'm not sure what "often" means for you.

RecodeLiner commented 8 months ago

Good afternoon everyone, I am translating a multiplatform project from compose image loader to kamel, and from it I decided to translate it to coil, I took the implementation on ktor and ran into a problem: Locally in IDE everything works fine, release on android also gives images correctly, but when I make release on desktop(msi for windows) I face the problem that the same link that works well for me in ide and in browser, for some reason gives error condition

DRSchlaubi commented 8 months ago

Sounds like proguard maybe?

RecodeLiner commented 8 months ago

Yes, I thought about that too, but to be honest, I don’t even know what could cause this, because coil documentation only says about coroutines and okhttp, but they are already specified in my proguard rules file

DRSchlaubi commented 8 months ago

It would be useful to actually see the error,

Coil components use java services, so maybe proguard erases them

RecodeLiner commented 8 months ago

I read the final error and there was (throwable=java.util.ServiceConfigurationError: coil3.util.FetcherServiceLoaderTarget: Provider coil3.network.ktor.internal.KtorNetworkFetcherServiceLoaderTarget not found) Fixed it with -keep class coil3.network.ktor.internal.* Thanks to everyone!

lepicekmichal commented 8 months ago

Hi, trying to use it on iOS (alpha6) and all is good but one thing, svg. While they do load, they are all tinted black. Am I doing something wrong? How do you install the decoder? I've got this:

setSingletonImageLoaderFactory {
    ImageLoader.Builder(it)
        .components { add(SvgDecoder.Factory()) }
        .build()
}

I'll create a separate bug if this is all it should take, thank you!

DatL4g commented 8 months ago

@lepicekmichal Known skia issue https://issues.skia.org/issues/40043341

master-lzh commented 8 months ago

Does anyone know how to use AsyncImage on iOS platform and apply rounded corners or circles through transformations like in android

colinrtwhite commented 8 months ago

@master-lzh You should use Modifier.clip for this. Transformations overall are obsolescenced by Compose's Modifier.graphicsLayer API.

master-lzh commented 8 months ago

@master-lzh You should use Modifier.clip for this. Transformations overall are obsolescenced by Compose's Modifier.graphicsLayer API.

Thanks a lot, I tried it yesterday and it's working now

nickfaces commented 7 months ago

Hi! I tested 3.0.0-alpha06 on android and iOS, but I can't understand how to set the headers for setting auth cookies.

guillermolc commented 7 months ago

Hi everyone i received this error on my wasm web impl Access to fetch at ... from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

im using 3.0.0-alpha06 version on my project, any tip to solve this?

joreilly commented 7 months ago

Some related info here fwiw https://github.com/qdsfdhvh/compose-imageloader/issues/446

guillermolc commented 7 months ago

Hi @joreilly i checked that but isn't working The image loader class have a constructor that require a context and it doesn't have a lambda to add new components only can read those

realityexpander commented 7 months ago

@guillermolc

Hi everyone i received this error on my wasm web impl Access to fetch at ... from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

im using 3.0.0-alpha06 version on my project, any tip to solve this?

Did you set up CORS on your server to allow the request to go thru on the browser side?

You may have to use a proxy service to access your images, like this one: https://wsrv.nl/