I have been looking for an answer to this question for several days and so on until the end, I have not completely figured it out. It is worth clarifying that I am looking for a way not just to save the screenshot as a file, but to get an array of bytes and array of bytes decoded to png/jpg or another lightweight image format. The first way i tried was screenshot-rs crate, code like this:
let s = match get_screenshot(0) {
Ok(it) => it,
_ => return,
};
let mut buf = Vec::<u8>::new();
let encoder = PngEncoder::new(&mut buf);
unsafe {
match encoder.encode(
std::slice::from_raw_parts(s.raw_data(), s.raw_len()),
s.width() as u32,
s.height() as u32,
image::ColorType::Rgba8,
) {
Ok(it) => it,
_ => return,
};
}
(I use png encoder too)
Formally, this code works but works very slowly (around ~5 sec) and producec screenshot with switched blue and red color channels.
After this i start trying to use winapi to capture screenshot, but my knowledge about winapi, hundreds of data types and what i have to do now (this doesnt work properly)
let x1 = GetSystemMetrics(78);
let y1 = GetSystemMetrics(79);
let x2 = GetSystemMetrics(76);
let y2 = GetSystemMetrics(77);
let w = x2 - x1;
let h = y2 - y1;
let hdc_screen = GetDC(ptr::null_mut());
let hdc = CreateCompatibleDC(hdc_screen);
let h_bitmap = CreateCompatibleBitmap(hdc_screen, w, h);
let obj = SelectObject(hdc, h_bitmap as HGDIOBJ);
let status = BitBlt(hdc, 0, 0, w, h, hdc_screen, x1, y1, SRCCOPY);