我想知道如何截取特定窗口的一部分。应用程序顶部可能有一个覆盖层(游戏覆盖层)隐藏了我感兴趣的内容。我想找到一种方法来只截取应用程序的屏幕截图,忽略覆盖层或者会出现什么顶。
而且我想知道是否有可能优化它以获得 ~5 截图/秒
现在我用以下代码尝试了screenshots cargo package:
use opencv::{core, highgui, imgcodecs};
use screenshots::Screen;
use std::{time::Instant};
use opencv::core::{log, Mat};
const WIDTH: i32 = 275;
const HEIGHT: i32 = 275;
fn get_img(screen: Screen) -> Mat {
let image = screen.capture().unwrap();
let buffer: Vec<u8> = image.into();
// Change image type to OpenCV Mat
let original_image: Mat = imgcodecs::imdecode(&core::Mat::from_slice(buffer.as_slice()).unwrap(), imgcodecs::IMREAD_COLOR).unwrap();
return original_image;
}
fn main() {
let window_name = "test".to_owned();
highgui::named_window(&window_name, highgui::WINDOW_NORMAL).unwrap();
highgui::resize_window(&window_name, WIDTH, HEIGHT).unwrap();
let screens = Screen::all().unwrap();
let screen = screens[1].clone();
let mut img = get_img(screen);
loop {
let now = Instant::now();
img = get_img(screen);
// print in console the time it took to process the image
println!("{} ms", now.elapsed().as_millis());
}
}
但是似乎不可能只截取叠加层后面的特定窗口的屏幕截图。
我用
cargo run --release
目标操作系统是Windows,我也在Windows下开发。
ps :我将我的图像转换为 OpenCV Mat 用于我的下一部分代码
您可以使用
winapi
和 user32
repo 获取任何窗口截图。
错误的是你可能使用了不能在 Windows 上运行的 onencv 库。
这是我的示例代码。假设我们有一个窗口调用“Chrome”
use winapi::um::winuser::{FindWindowA, GetWindowRect, GetDC, ReleaseDC};
use winapi::shared::windef::RECT;
use std::ptr::null_mut;
fn main() {
let window_title = "Chrome";
let hwnd = unsafe { FindWindowA(null_mut(), window_title.as_ptr() as *const i8) };
let mut rect = RECT::default();
unsafe {
GetWindowRect(hwnd, &mut rect);
let width = rect.right - rect.left;
let height = rect.bottom - rect.top;
let hdc = GetDC(hwnd);
let mut buf: Vec<u32> = vec![0; (width * height) as usize];
let pitch = width * std::mem::size_of::<u32>() as i32;
winapi::um::wingdi::BitBlt(hdc, 0, 0, width, height, hdc, 0, 0, winapi::um::wingdi::SRCCOPY);
winapi::um::wingdi::GetDIBits(hdc, null_mut(), 0, height as u32, buf.as_mut_ptr() as *mut _,
&mut winapi::um::wingdi::BITMAPINFO {
bmiHeader: winapi::um::wingdi::BITMAPINFOHEADER {
biSize: std::mem::size_of::<winapi::um::wingdi::BITMAPINFOHEADER>() as u32,
biWidth: width,
biHeight: height * -1,
biPlanes: 1,
biBitCount: 32,
..Default::default()
},
..Default::default()
}, winapi::um::wingdi::DIB_RGB_COLORS);
ReleaseDC(hwnd, hdc);
}
}
您可以通过键入
cargo run
来运行它。
希望对你有帮助