Kamel-Media / Kamel

Kotlin asynchronous media loading and caching library for Compose.
Apache License 2.0
657 stars 25 forks source link

GIF suppport #12

Closed filwiesner closed 1 month ago

filwiesner commented 2 years ago

Does Kamel support GIFs (animated image)? I couldn't find any mention of it in README or using repository search.

alialbaali commented 2 years ago

No it doesn't. The reason is that Kamel focuses more on Desktop than Android. You can see this issue which has a sample about a GIF Composable, however, last time I tested it, the performance was terrible. And that's the reason, Kamel doesn't support loading GIFs yet.

DRSchlaubi commented 1 year ago

Any updates?

luca992 commented 1 year ago

@DRSchlaubi If you or someone else creates a pr with animated image support I can take a look. I don't have time to look into it atm

PMARZV commented 11 months ago

any updates on this?? this could be a game changer! Btw this library is far better than coil imo, had a lot of problems and when i changed to this one for my multiplatform migration, all the problems disappeared!!! Congrats on the library!

luca992 commented 11 months ago

I still don't have time at the moment. Prs are welcome

luca992 commented 8 months ago

Next release should have support for gifs 👍

https://github.com/Kamel-Media/Kamel/assets/4157455/9dc83dd2-23a5-42b9-aad2-d36cb1f2a68b

luca992 commented 8 months ago

released in v1.0.0-beta.5 lmk if there a problems... as I've only tested with a single gif :sweat_smile:

PMARZV commented 8 months ago

testing it tomorrow

PMARZV commented 8 months ago

i have tested it and i works perfectly.

I have noticed that when using "media.kamel:kamel-image-default:1.0.0-beta.5" in common main and targeting only (for example) desktop, the build fails because it doesnt find "io.ktor:ktor-client-core:3.0.0-wasm2" (even though im not targeting wasm), it only works after adding "maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental")" to dependencyResolutionManagement in settings gradle. I have then tested to add the same Kamel dependency to an android project and same thing.

Btw minSdk = 28 in android, that must be because you require something that its not available in lower versions right? (Error: uses-sdk:minSdkVersion 21 cannot be smaller than version 28 declared in library [media.kamel:kamel-decoder-animated-image-android:1.0.0-beta.5])

Without these issues, everything is working as expected!

luca992 commented 8 months ago

@PMARZV Yeah I'm still waiting for a non-experimental ktor build with wasm support. Didn't realize it would require consumers of the library to have to add that repo though. On the stable 0.9.x branch I'm still keeping wasm and non-wasm builds separate so the the non-wasm build can have a stable ktor... But for the beta, I just don't want to deal with it haha. I'm just going to keep it beta until a non-experimental ktor build is out.

And unfortunately, the skia rendering implementation is not available on android... and AndroidAnimatedImage is API level 28.

There's probably a way to make android decoder that supports API level 21 by adding a dependency (or writing something custom)... but I probably would make that a separate android only decoder. If anyone wants to make a pr to figure that out, be my guest.

fluxxion82 commented 2 months ago

@luca992 I'm trying to display a gif that I have in my common resources:

KamelImage(
        resource = {
            asyncPainterResource(Res.drawable.logo_animated_gif)
        },
        modifier = modifier,
        contentDescription = "logo",
    )

but not seeing anything show up in my apps. I'm using version 1.0.0-beta.7 with dependencies kamel-image and kamel-decoder-animated-image. Am I missing anything? I've also tried to passing in the path of my gif to asyncPainterResource as well with no luck.

luca992 commented 2 months ago

@fluxxion82 does the file have a .gif extension? Currently picking a decoder is done by the file extension. Also, you can try printing any error with the onFailure handler to see what might be failing if anything

fluxxion82 commented 2 months ago

@luca992 yes, the file has a .gif extension. I'm getting the following error from the onFailure handler:

IllegalStateException ``` java.lang.IllegalStateException: Unable to find a fetcher for class org.jetbrains.compose.resources.DrawableResource at io.kamel.core.utils.ConfigUtilsKt.findFetcherFor(ConfigUtils.kt:32) at io.kamel.core.ImageLoadingKt$loadImageBitmapResource$$inlined$loadResource$1.invokeSuspend(ImageLoading.kt:82) at io.kamel.core.ImageLoadingKt$loadImageBitmapResource$$inlined$loadResource$1.invoke(Unknown Source:8) at io.kamel.core.ImageLoadingKt$loadImageBitmapResource$$inlined$loadResource$1.invoke(Unknown Source:4) at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:57) at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:226) at kotlinx.coroutines.flow.FlowKt__ErrorsKt.catchImpl(Errors.kt:152) at kotlinx.coroutines.flow.FlowKt.catchImpl(Unknown Source:1) at kotlinx.coroutines.flow.FlowKt__ErrorsKt$catch$$inlined$unsafeFlow$1.collect(SafeCollector.common.kt:109) at androidx.compose.runtime.SnapshotStateKt__SnapshotFlowKt$collectAsState$1$1$2.invokeSuspend(SnapshotFlow.kt:70) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102) at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:96) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:589) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:816) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:720) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:707) ```
luca992 commented 2 months ago

@fluxxion82 oh I see. There is not currently a compose multiplatform DrawableResource fetcher implementation made. I kinda halfway made the logic for it that would be needed if you want to make your own fetcher for it here: https://github.com/Kamel-Media/Kamel/blob/main/kamel-samples/src/commonMain/kotlin/io/kamel/samples/FileSample.kt

luca992 commented 2 months ago

This was all made before compose multiplatform resources was even a thing. So that will have to go on the todo list. Prs are welcome though.

Right now we only have standard jvm, and android resource fetchers made.

fluxxion82 commented 2 months ago

@luca992 ok, thanks. I got the gif working on android but running into a number of issues when trying to run on iOS. also, when I use `asyncPainterResource("drawable/logo_animated.gif") instead of trying to use the DrawableResource, I get this exception:

java.net.ConnectException ``` java.net.ConnectException: Connection refused at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:762) at io.ktor.network.sockets.SocketImpl.connect$ktor_network(SocketImpl.kt:50) at io.ktor.network.sockets.SocketImpl$connect$1.invokeSuspend(Unknown Source:15) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102) at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:96) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:589) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:816) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:720) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:707) ```

which I found odd since I'm not making any network requests.

when I model things after the FileSample code, I get some errors with iOS, namely some KLIB resolver: Could not find "org.jetbrains.kotlinx:kotlinx-io-bytestring" errors (i think i saw these when i tried to rebuild the project too), and I'm wondering if it has something to do with the kotlin version I'm using (2.0.20). Even when I built a version of kamel with updates to lib versions (compose, ktor, kotlin), I saw some other errors (ie kotlin.native.internal.IrLinkageError).

I might try to take another shot at getting things to work on iOS. if you have any insights into any of the issues I've mentioned, let me know.

luca992 commented 2 months ago

"drawable/logo_animated.gif" isn't a valid way to get a resource. You have to use the Int id on android. If you wanted to try do something like "drawable/logo_animated.gif" you'd need to make your own string mapper

luca992 commented 2 months ago

And idk. I can't help with your other issues without a way to duplicate it.