Add codec-level scaled image decoding#3934
Conversation
Avoid full-resolution CPU and memory costs when callers only need a smaller target, while documenting codec and web fallbacks.
|
I have signed the CLA! |
wcandillon
left a comment
There was a problem hiding this comment.
Thank You for making this PR.
- Do you have examples/were you able to run some measurements on this? Currently the image is decode on UI thread (lazy) and this would decode the image on the JS thread, I'm curious to learn more about how you tested/measured this.
- I think this should be an option in existing decoding method rather than a new method.
- On web, FilterMode.Linear + MipmapMode.None is likely the wrong default
|
Thank You for making this PR. Here are my current thoughts on the topic:
|
|
Hi William! Did some benchmarking and this does not actually help, unfortunately. I do have a patch that lets you do scaled decoding for JPEGs, but it does not work for PNGs and so I'm not sure if that would still be helpful. I wish there was a universal patch. I guess the long-term solution for our app is to just maintain copies at different aspect ratios, instead of trying to decode lower-quality versions via Skia paths. Would scaled JPEG decoding help? In our app we do so much decoding that I feel like we're always looking for ways to speed this up. Curious if you have thoughts on good directions on streamlining this! |
Summary
Skia.Image.MakeImageFromEncodedScaled(data, targetWidth, targetHeight?)SkCodec::getScaledDimensions()andgetImage()on native platforms instead of always creating a full-resolution decoded imageMotivation
Callers often need a thumbnail or an image for a smaller canvas/compositing target. Decoding every source at full resolution first adds avoidable CPU work and peak memory pressure, especially for large encoded images. This API lets native codecs decode at their closest supported scale. A codec without scaled-decode support falls back to source resolution; CanvasKit does not expose codec-level scaled decoding, so Web falls back to full decode followed by resize.
No performance numbers are claimed here. A follow-up benchmark can compare wall time and peak resident memory for full decode versus scaled decode across representative large JPEG, PNG, and WebP inputs and several target scales.
Semantics
targetWidthis required and must be a positive finite number.targetHeight, when provided, must also be positive and finite.null.Validation
yarn workspace @shopify/react-native-skia tscyarn workspace @shopify/react-native-skia test src/renderer/__tests__/e2e/Image.spec.tsx --runInBand(5 tests)pod installincluding React Native codegenReactTestAppThis is a draft until Android CI or a local JDK-backed build validates the shared C++ binding through the Android toolchain.