coil-kt / coil

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

Support animated image on iOS #2347

Open master-lzh opened 4 months ago

master-lzh commented 4 months ago

Is your feature request related to a problem? Please describe. Any plans to support animated images such as gif/animated webp on multiplatform?

Describe the solution you'd like Right now only Android platforms can play animated images, on iOS it will only show the first frame of the image

Additional context

colinrtwhite commented 4 months ago

I think this is something we could support (no timeline) as I believe Skiko/Skia already support decoding GIF frames. We'd just need someone to write a custom Decoder that uses Skiko to implement support. Open to a PR if someone wants to contribute this!

LaatonWalaBhoot commented 4 months ago

@colinrtwhite Perhaps this could help? https://github.com/panpf/sketch/blob/main/docs/wiki/animated_image.md I am quite a noob so just suggesting if this could be used as a reference?

valeriyo commented 2 months ago

Upvoting 👍

outadoc commented 1 month ago

Quite interested by this feature as well!

Another possible source of inspiration, there is an optional component in jetbrains/compose-multiplatform that brings animated image support to Compose Desktop.

From what I understand, Compose for iOS also uses Skia, so that could be a good starting point.

colinrtwhite commented 1 month ago

Hey folks, I did a quick POC here (not production ready) to see how this could be done on non-Android platforms. It works OK, but for some reason the GIFs seem to lag a lot on desktop (I didn't test other platforms). You can test this yourself by checking out that branch and running ./gradlew samples:compose:run then tap on JPG in the top right. Not sure what's the cause, but a list of GIFs currently runs poorly. I think we might have to pre-decode the GIF frames ahead of time, but that will consume a lot more memory.

No timeline for this to be released as I want to focus on releasing Coil 3 stable before settling on an API and productionizing this, but this can hopefully be part of a 3.1 or 3.2. If you need this ASAP, you can copy the rough AnimatedSkiaImageDecoder I added here. Just register it on your ImageLoader on non-Android platforms with ImageLoader.Builder.componentRegistry { add(AnimatedSkiaImageDecoder.Factory()) }.

EDIT: Added an option to prerender frames. It fixes the main thread choppiness, but significantly increases the decode time for long GIFs. I think we'll have to do something hybrid (decode a couple frames up front then try to decode the remaining frames just in time).

outadoc commented 1 month ago

@colinrtwhite That made my day, thank you! 🎉

I've tested your code on iOS, on my hobby project, with prerenderFrames = true.

Otherwise, everything played pretty smoothly! I wasn't particularly focused on performance, and tested with fairly small GIFs, so take that with a grain of salt.

valeriyo commented 1 month ago

@outadoc / @colinrtwhite - guys, thanks for pushing this forward! 🎉

outadoc commented 1 month ago

I've played with @colinrtwhite's POC a bit more and could get it to work with looping GIFs. Again, not production-ready, but seems to work okay for my use case 😄

Posting it here in case it helps for the final implementation or someone else's version.

https://github.com/outadoc/just-chatting/blob/3fedd07193a08d064d473090cdf1e5146ad6cd98/shared/src/iosMain/kotlin/fr/outadoc/justchatting/utils/coil/AnimatedSkiaImageDecoder.kt

1060114835 commented 4 weeks ago

@outadoc
Thanks! I have used the decoding ability you provided, and the ability to run through the gif image on a non-JVM platform. I want to ask is this ability to support webp format? through your source code I see that it is limited to loading GIF format by if-else

outadoc commented 4 weeks ago

I want to ask is this ability to support webp format? through your source code I see that it is limited to loading GIF format by if-else

@1060114835 I've hardcoded checks for GIFs in the snippet because I haven't tried the code on anything else than GIFs and I actually don't know where to find the formats supported by Skia. I wouldn't be surprised if it supports webp or APNG with very few changes

1060114835 commented 4 weeks ago

@outadoc I try to load .webp image,it run!