Files
egui/examples/screenshot
Lucas Meurer 416dd85acb Make ViewportCommand::Screenshot callback based (#8489)
Migration guide for the changelog:
`ViewportCommand::Screenshot` was changed to be callback based.
Previously you needed to iter the input events to check for the
screenshot (but didn't need interior mutability):
```rs
[derive(Default)]
struct MyApp {
    screenshot: Option<Arc<egui::ColorImage>>,
}
impl eframe::App for MyApp {
    fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
        if ui.button("Screenshot").clicked() {
            ui.send_viewport_cmd(ViewportCommand::Screenshot(UserData::default()));
        }

        let image = ui.input(|i| {
            i.events
                .iter()
                .filter_map(|e| {
                    if let egui::Event::Screenshot { image, .. } = e {
                        Some(Arc::clone(image))
                    } else {
                        None
                    }
                })
                .next_back()
        });
        
        if let Some(image) = image {
            self.screenshot = Some(image);
        }
    }
}
```

Now you need to use a mutex, channel, or some other sync primitive to
get the result:
```rs
#[derive(Default)]
struct MyApp {
    screenshot: Arc<Mutex<Option<Arc<egui::ColorImage>>>>,
}
impl eframe::App for MyApp {
    fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
        if ui.button("Screenshot").clicked() {
            let ctx = ui.ctx().clone();
            let screenshot_mutex = self.screenshot.clone();
            ui.request_screenshot(move |screenshot| {
                screenshot_mutex.lock().replace(screenshot);
                ctx.request_repaint();
            });
        }
    }
}
```
----



This implements a callback-based screenshot api for egui

Upsides over `ViewportCommand::Screenshot`:
- More convenient api: `ctx.request_screenshot(|screnshot| ...)` (and no
need to downcast UserData)
- Reading screenshot data doesn't require rendering another frame
- Should allow us to add recording as a plugin without special hooks in
egui_kittest (otherwise capturing the last frame would have required
custom hooks in kittest)
- This was also a problem in
[kittest_inspector](https://github.com/rerun-io/kittest_inspector): When
streaming a real app, the frame seen was always a couple frames behind
when the app was idle
2026-09-08 16:06:18 +02:00
..

Example how to take screenshots and display them with eframe/egui.

cargo run -p screenshot