-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Multiple svg images render blurry #3501
Comments
This appears to be due to the the caching done by the ImageLoader. If you call If anyone has guidance on how to implement that automatic eviction I'd be happy to take a shot at it. |
Update `resvg` from v0.28 to v0.37. Remove related, unnecessary entries from `deny.toml`. ⚠ In example `images` ferris is scaled differently, but I guess that now it scales in expected way (takes all available space; before this PR it takes up to space that, was available at first render- it does not upscale). This PR is minimal adaptation to new `resvg` api and small related simplification, however it should be considered to update loaders (currently if svg image initially was small and was scaled up it will be blurred, see #3501). As svg image now scales over render size, problem will be more often seen now. (currently `SvgLoader` theoretically should rerender for different sizes (but I guess it will result in memory leak in that case), but refreshing is stopped earlier in `DefaultTextureLoader`). I have initial version of loaders update, that will fix issue with svg scaling (and also enable e.g. reloading image if file has been changed), I will submit these changes in separate PR once this one is merged. Closes <#3652>.
I was looking into this, and found that the SVG loader actually includes the size hint as part of its key: egui/crates/egui_extras/src/loaders/svg_loader.rs Lines 12 to 15 in 5cf99c6
Which would solve this problem, but also sounds kind of dangerous, because if you have an SVG that fills the available space, you would end up with hundreds of copies at different sizes as the UI is resized. But in any case, it isn't working as intended, because the image loader is called by the texture loader, which does not take the size into account. egui/crates/egui/src/load/texture_loader.rs Lines 13 to 24 in 5cf99c6
So one way to work around this would be to copy this default texture loader to your code and change it to take the size into account like the SVG loader does, then add it to the context using add_texture_loader. Maybe this should be added to egui itself, but it seems like it would be hard to find a balance between CPU and RAM usage and image quality that would work for every use case. |
I'm experiencing this as well with the SvgLoader and am trying to find a good interim solution. @YgorSouza's post has me on the right track, instead of using a So far I've noticed the following behaviors from debugging the caching of my custom svg loader:
I don't think anything special is happening here on my end, I'm just using the painter api to paint into a rectangle. I think the next thing to wrap my head around:
|
Ok, I see what I was missing: TextureLoader is the abstraction level that paint uses to cache an svg. |
any news about this issue ? |
Hi @chianti-ga I was able to work around this issue by implementing my own loaders where I changed the cache-key to represent both file uri and rendered size, so that once I rendered a svg at a given size it remains cached unless otherwise forgotten. |
@molenick why not submit a pull request with this solution? I think it's a straightforward way to address the issue. |
@molenick I see my solution as being custom to the need of my project, and after working with it it seems to me like the Loader API is the intended api to customize caching behavior to suit your app's need. However it seems like this is a common use case given the popularity of this issue, so if the maintainers think this is a worthwhile addition I'd be happy to contribute. I think the general behavior of this loader is "cache by uri and render size" instead of "cache by uri" and is pretty simple to write. I think there are a lot of people who "just want to use egui" and are surprised by the default caching behavior so this could be a good change for users that want to render svg at different size without worrying about egui's caching subsystem. |
@chianti-ga Whoops, realized I responded to myself up in that last comment |
Yah, Having to work around this with a lot of custom code is probably not specific to your app, @molenick, although perhaps the specific way you do it is. |
I recommend clearing the cache automatically when adjusting the UI scale so that images are not cached for every possible UI scale. EDIT: #3453 may be relevant? |
Describe the bug
When adding multiple svg images from the same source but with different size, the latter image renders blurry as if it takes the texture from the first added (smaller) image.
To Reproduce
Code to reproduce:
Image i used to test:
Expected behavior
Both vector images must look sharp and render at respective for its size resolution
Screenshots
Desktop (please complete the following information):
Additional context
Reproduced on win11, android 10, eframe, egui-winit + egui-wgpu implementation, egui 0.23.0, master branch (as the time of writing)
The text was updated successfully, but these errors were encountered: