Convert frame from scrap crate to imagebuffer in image crate

I'm using the scrap library to take screenshots. I want to process the screenshot before saving it.
In the example the author converts the image format to bgra formt before saving it. I modified the code a bit to convert it to RGB.

let one_second = Duration::new(1, 0);
let one_frame = one_second / 60;
let display = Display::primary().expect("Couldn't find primary display.");
let mut capturer = Capturer::new(display).expect("Couldn't begin capture.");
let (w, h) = (capturer.width(), capturer.height());
loop {
    // Wait until there's a frame.

    let buffer = match capturer.frame() {
        Ok(buffer) => buffer,
        Err(error) => {
            if error.kind() == WouldBlock {
                // Keep spinning.
                thread::sleep(one_frame);
                continue;
            } else {
                panic!("Error: {}", error);
            }
        }
    };
    
    println!("Captured! Flipping...");
       // Flip the ARGB image into a RGB image.
    let mut bitflipped = Vec::with_capacity(w * h * 4);
    let stride = buffer.len() / h;

    for y in 0..h {
        for x in 0..w {
            let i = stride * y + 4 * x;
            bitflipped.extend_from_slice(&[
                buffer[i],
                buffer[i + 1],
                buffer[i + 2],
            ]);
        }
    } 

However, instead of doing that, I'd like to directly import the [u8] buffer hidden in the frame like this:

   let img = image::ImageBuffer::from_raw(w as u32,h as u32,*buffer).unwrap();
   let img = image::ImageRgba8(img);

I got this error:

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
  --> src/main.rs:69:18
   |
69 |        let img = image::ImageBuffer::from_raw(w as u32,h as u32,*buffer).unwrap();

I saw in the source code the following (https://github.com/quadrupleslap/scrap/blob/master/src/quartz/frame.rs):

pub struct Frame {
    surface: IOSurfaceRef,
    inner: &'static [u8]
}

....

impl ops::Deref for Frame {
    type Target = [u8];
    fn deref<'a>(&'a self) -> &'a [u8] {
        self.inner
    }
}

Instead of *buffer you can pass &*buffer to get an &[u8].

This still might not work, however, since I think ImageRgba8 requires a Vec<u8> buffer. You might need to convert from a different image type.

That solved that one.

^^^ expected struct std::vec::Vec, found &[u8]
Just like you said. So I did Vec::from(&*buffer) instead.

Thanks

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.