-
Notifications
You must be signed in to change notification settings - Fork 35
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
Subsampling support improvements #120
Comments
I love this detailed feedback! 1: I'm sorry I don't fully understand this. Are you using Coil for loading your images? If so, could you clarify why does 2, 3, 4: I agree that |
Thank you! I think I got a bit confused about the first item. In my app, I use Telephoto for 2 use cases – to display the actual photos and to render the PDF as I described above. The photos were not subsampled as well – and I assumed it was related to using a custom model that doesn't fit into one of the categories. I've double-checked the The issue with PDF rendering still remains though. In theory, you could write a fetcher that renders the page in its full scale to disk cache – but considering that the PDF renderers will output raw bitmap only (not a stream or something), it has to be stored in-memory during the rendering which kinda makes the subsampling useless (OOM can happen). |
I'm glad you got it working, but I feel bad that you had to dive into the source code to figure this out. Is there a better way I could surface this information for developers?
Yea that's fair. I've just pushed a commit that makes |
Thank you! I think the documentation is great – I noticed that the image should be sub-sampled from very beginning, it's just it wasn't working for my case, so I assumed after brief reading of the code that it's related to the model – not to the disk cache as well. |
@bvitaliyg It is done. could you try out |
Thank you! I cloned the repo and published the snapshot to Mavel local repository. I've also encountered an FPS drop when the PDF was zoomed. I checked out the threads and I found out that Never the less, custom image sources might take some time to render (including Everything else worked like charm! Looking forward to the next release |
Glad to hear!
While I'd like to advocate that functions should never make any assumptions about the thread they're called from, you're right that I should probably mention that Are you building an OSS for rendering PDFs? Let me know if you need any other changes. |
Agreed, we shouldn't assume on which thread the suspend functions are called. Just thought if you decode the subsampled bitmaps off the main thread it can result in smoother user experience overall if you currently invoke I'm building the PDF renderer, currently closed-source, but I'm considering making it OSS when I it's done. Thank you again for the library, it already has a lot of features I need (such as having coordinates of tap/long tap), and it's super-stable. Will let you know if I need any other changes :) |
First of all – thank you for the library! I am very happy to use it, but I recently encountered a few limitations for subsampling. Here they are:
By default, it doesn't work with anything else but default models for specific models in official loaders support modules – like here it supports only
File
andUri
models for Coil3.There are 2 ways to support custom models: using
SubSamplingImage
(and losing most of the benefitsZoomableImage
UI tweaks and caching of image loader) or forkingZoomableImageSource
implementation (Coil3ImageSource
in this case). Surely there could be an option with simpler API – like having a specific interface that loads subsampled images as one of the arguments ofZoomableImage
and handles nothing else (unlike, for instance,Coil3ImageSource
, which handles interaction with image loader to get a preview).There's no efficient way to provide a custom Bitmap
SubSamplingImageSource
. You can use a file, an asset, a resource,Uri
, or aSource
(akaInputStream
2.0). But there's no way to use some sort of customBitmapFactory
. This makes using something likePdfRenderer
very difficult – the only way to use it would be to take the entire decoded bitmap into memory, compress it into one of the file formats, and provide aSource
from the bytes of this format. This takes a lot of memory and CPU time.The reason why the
SubSamplingImageSource
is limited is because it's tightly coupled with the usage ofBitmapRegionDecoder
and all ways of customising theSubSamplingImageSource
are restricted by it. I think having the option to use a custom Factory would be a much more flexible choice. Also, usingBitmapRegionDecoder
blocks subsampling to be migrated to KMP.Another method that makes working creating custom
SubSamplingImageSource
difficult isSubSamplingImageSource.peek()
. It ties the implementation to using one or another form of bytes array to decode the image from. That wouldn't make sense forPdfRenderer
, for example. Internally, this method is used for:I think a better option would be to have these parameters provided explicitly by
SubSamplingImageSource
. The subclasses could still read EXIF and have the same checks done if they rely on compressed image formats (peek()
could still be there, but declared as private).So, to summarise: an additional parameter for subsampling images could be added to
ZoomableImage()
. It could exist as a loader-agnostic interface, something likesubsampler: suspend (Model) -> SubSamplingImageSource
. The could be some default implementations for standard models.SubSamplingImageSource
itself could havepeek()
replaced withgetImageOrientation()
,getImageDimensions()
,canBeSubsampled()
,canBeRead()
, anddecoder()
returning an abstract decoding interface (with something likesuspend fun decodeRegion(rect: IntRect, dstSize: IntSize, options: Options): Image?
) – or this method could replacedecoder()
itself.This is just one of the potential API surfaces, any other implementation would also be great as long as it solves the problems described above.
What do you think? I could try to help with the PR if you're okay with the changes – or if you clarify what you think could be changed.
The text was updated successfully, but these errors were encountered: