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

Rework pre-scaling / caching of images #1176

Open
wutschel opened this issue Oct 27, 2024 · 2 comments · May be fixed by #1186
Open

Rework pre-scaling / caching of images #1176

wutschel opened this issue Oct 27, 2024 · 2 comments · May be fixed by #1186

Comments

@wutschel
Copy link
Collaborator

wutschel commented Oct 27, 2024

While analyzing memory consumption I also found some more interesting facts on the behaviour when caching pre-scaled images.

Memory impact of color space creation and scaling

If an image dimension is not changed (image and target resolution are identical), high memory consumption is driven by creating a new color space via CGColorSpaceCreateDeviceRGB(). If, in case of identical target/image resolution, no new color space is created, e.g. when the correct color space is already given, the memory consumption is far less (hundreds of MBs less for about 400 thumbs). But, once rescaling to a different resolution is done, this does not matter anymore. The memory consumption is always high in this case. Nothing I can do about it as far as I can see.

Pre-scaling done only half-way

What I realized, after working in-depth / reviewing the implementation, is, that thumb images are not really fully scaled to the target resolution, which would require content fill method to be taken into account at this stage. In fact, the image's aspect ratio is kept, and the thumbs are only scaled half-way to meet to minimum resolution requirements. Examples:

  • Target (300x300), image (600x900) -> scaled to 300x450
  • Target (300x300), image (900x600) -> scaled to 450x300

This will cause some scaling still do be processed by UIImageView, if target and image have different aspect ratios. My assumption is that this might cause some of the stuttering reported by users. It also causes the memory and flash consumption to be higher than desired as, in case of mismatching aspect ratios, always more pixels are kept as required.

Impact of UIImageView scaling

I reworked the pre-scaling, which also allows to remove doubled code, and to reduce the flash size of the image cache. But there are (slight) differences in image quality when doing all scaling in advance (using CGContextDrawImage(...)), which removes the scaling part of UIImageView. Obviously the CG scaling results in smoother results (more interpolation, less aliasing), whereas the UI scaling at first glance results in a sharper image.

When improving UIImageView's the scaling method by setting

imageview.layer.minificationFilter = kCAFilterTrilinear;
imageview.layer.magnificationFilter = kCAFilterTrilinear;

this visual differences become less prominent. I take this as sign that the standard UI scaling shows some ringing or undesired granularity, and not more details. Still I prefer the UI trilinear scaling over what CG scaling achieves. But to reduce the load and stutter via scrolling the pre-scaling is needed, and using trilinear UI scaling is counter productive.

Screenshots:
Bildschirmfoto-2024-10-27-um-11-19-09

Edit: To put the above zoomed images into full context: https://ibb.co/30czCwP

@kambala-decapitator
Copy link
Collaborator

honestly, I don't see any difference in the images at all =)

@wutschel
Copy link
Collaborator Author

honestly, I don't see any difference in the images at all =)

There is -- subtle, but visible. Just open full size image (click the link, and then enlarge to full resolution). I know our testers :)

@wutschel wutschel linked a pull request Nov 3, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants