1use std::convert::TryFrom;
2use webkit2gtk::{SnapshotOptions, SnapshotRegion, WebView, WebViewExt, LoadEvent};
3use cairo::{ImageSurface, Format};
4use image::{ImageBuffer, DynamicImage, RgbaImage};
5
6pub trait WebViewSnapshotListener {
9 fn page_load_snapshot_listener<F: 'static + FnMut(RgbaImage) + Send + Clone>(&self, callback: F) -> &Self;
10}
11
12impl WebViewSnapshotListener for WebView {
13 fn page_load_snapshot_listener<F: 'static + FnMut(RgbaImage) + Send + Clone>(&self, callback: F) -> &Self {
14 self.connect_load_changed(move |wv, load_event| {
15 if load_event != LoadEvent::Finished {
16 return;
17 }
18
19 let mut callback = callback.clone();
20 wv.get_snapshot(
21 SnapshotRegion::FullDocument,
22 SnapshotOptions::empty(),
23 None::<&gio::Cancellable>,
24 move |snapshot| {
25 let surface = snapshot.unwrap();
26 let mut image_surface = ImageSurface::try_from(surface).unwrap();
27
28 let format = image_surface.get_format();
29 if format != Format::ARgb32 {
30 unimplemented!("Not implemented for image type {:?} yet", format)
31 }
32
33 let width = image_surface.get_width() as u32;
34 let height = image_surface.get_height() as u32;
35 let data = image_surface.get_data().unwrap().to_vec();
36
37 let image = DynamicImage::ImageBgra8(ImageBuffer::from_vec(width, height, data).unwrap()).to_rgba();
38
39 callback(image);
40 },
41 );
42 });
43
44 self
45 }
46}