Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support animated image on iOS #2347

Open
master-lzh opened this issue Jul 1, 2024 · 11 comments
Open

Support animated image on iOS #2347

master-lzh opened this issue Jul 1, 2024 · 11 comments
Labels
enhancement New feature or request help wanted Issues that are up for grabs + are good candidates for community PRs

Comments

@master-lzh
Copy link

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

@master-lzh master-lzh added the enhancement New feature or request label Jul 1, 2024
@colinrtwhite
Copy link
Member

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!

@colinrtwhite colinrtwhite added the help wanted Issues that are up for grabs + are good candidates for community PRs label Jul 1, 2024
@LaatonWalaBhoot
Copy link

@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
Copy link

Upvoting 👍

@outadoc
Copy link

outadoc commented Oct 2, 2024

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
Copy link
Member

colinrtwhite commented Oct 4, 2024

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
Copy link

outadoc commented Oct 4, 2024

@colinrtwhite That made my day, thank you! 🎉

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

  • Non-GIF (e.g. PNG) images are processed by the decoder, which breaks them. To work around that, I borrowed DecodeUtils.isGif from coil-gif, and use it like in coil3.gif.GifDecoder.Factory, which fixed the issue. I'm guessing a proper implementation would move the DecodeUtils to the common sourceset to avoid duplication.
  • Looping GIFs only play once -- I suppose some extra logic is needed here?

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
Copy link

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

@outadoc
Copy link

outadoc commented Oct 11, 2024

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
Copy link

@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
Copy link

outadoc commented Oct 24, 2024

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Issues that are up for grabs + are good candidates for community PRs
Projects
None yet
Development

No branches or pull requests

6 participants