-
I'm making an image editor, but ignore whatever just came to mind because I've already dealt with all the hard stuff using direct One of the places where I need to show images is the layer list. I need to show a rough preview of what each layer looks like. To do this I'm trying to create a 24x24 pixel thumbnail, newly generated every frame, and then show that as an Image in the UI. These images are raw RGBA8 byte buffers. All of the image loading stuff in egui is designed with the assumption that images are static or rarely changing. These images change constantly. What is the correct way to do this? Do I have to drop down to raw shaders? Load images normally but use Loading a new Texture with a new unique URI every frame sounds like it would destroy the frontend (e.g. eframe) and possibly cause memory leaks. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
For now I'm just rendering a whole entire painter rect per thumbnail pixel, which performs fine. This is how incredibly performance-insensitive this task is in my case. But there's a chance (a very likely one) this won't scale to very complex images on very weak hardware. |
Beta Was this translation helpful? Give feedback.
-
In my drawing app I just use another PaintCallback for each layer and render the texture there. It doesn't look that nice because it's not MipMapped, but it's simple and works well and doesn't cost much performance. But why do you need to recreate the thumbnails every frame? That must be sloooow. Can't you cache them and only recreate it when the layer was changed in some way? We have the Screenshot example where we also change an image every frame, seems like just using ctx.load_texture is fine (But still I don't recommend this if there is a better way): egui/crates/egui_demo_lib/src/demo/screenshot.rs Lines 64 to 69 in 6c1d695 |
Beta Was this translation helpful? Give feedback.
-
Here's my solution: have a TextureHandle that's created dynamically but if it already exists overwritten with if let Some(ref mut th) = layer.thumbnail
{
let mut th = th.to_mut::<egui::TextureHandle>().unwrap();
th.set(thumb_img.to_egui(), egui::TextureOptions::NEAREST);
}
else
{
let ctx = ui.ctx();
let thumb = thumb_img.to_egui();
let tex = ctx.load_texture(format!("{}", Uuid::new_v4().as_u128()), thumb, egui::TextureOptions::NEAREST);
layer.thumbnail = Some(Box::new(tex));
} painter.image(tx.id(), rect, [(0.0, 0.0).into(), (1.0, 1.0).into()].into(), egui::Color32::WHITE); |
Beta Was this translation helpful? Give feedback.
Here's my solution: have a TextureHandle that's created dynamically but if it already exists overwritten with
.set()
. The texture name is just a big random number converted to string.