-
-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
请问win11下为什么截取的图片会比实际窗口小很多,有没有什么办法可以截取窗口的大小 #128
Comments
大小应该没有计算窗口边框,只计算了绘制区域,这个是一个已知问题,解决有一点麻烦 |
好像是缩放导致的 |
显示器缩放参数,分辨率都给我下把,我复现下 |
缩放150% 屏幕分辨率3840*2160 |
获取窗口宽高应该按照下面这样,你可以试试 let width = window.width() * window.current_monitor().scale() |
没办法截取实际显示的大小吗? |
我也遇到了类似的问题。实际图片比窗口大很多。图片的快和高比实际窗口的大。填充了很多空白。这是多乘了 这种无效填充还会导致BGRA到RGBA时间大变长,其实可以加一个函数返回BGRA数据,例如opencv直接处理的就是BGRA格式。 基于以上情况删除这2行代码 https://github.com/nashaofu/xcap/blob/v0.0.10/src/windows/capture.rs#L140-L141 ,大多数情况下截图正常,但是少数Dxf这种游戏会缩小图片。且没有无效填充。为了解决缩小问题,可以把图片放大。如果获取的 #[allow(unused)]
pub fn capture_window(hwnd: HWND, scale_factor: f32) -> XCapResult<RgbaImage> {
unsafe {
let box_hdc_window: BoxHDC = BoxHDC::from(hwnd);
let rect = get_window_rect(hwnd)?;
let mut width = rect.right - rect.left;
let mut height = rect.bottom - rect.top;
let hgdi_obj = GetCurrentObject(*box_hdc_window, OBJ_BITMAP);
let mut bitmap = BITMAP::default();
let mut horizontal_scale = 1.0;
let mut vertical_scale = 1.0;
if GetObjectW(
hgdi_obj,
mem::size_of::<BITMAP>() as i32,
Some(&mut bitmap as *mut BITMAP as *mut c_void),
) != 0
{
width = bitmap.bmWidth;
height = bitmap.bmHeight;
}
let window_width = rect.right - rect.left;
let mut new_width = width;
let mut new_height = height;
// bitmap 获取失败也乘scale_factor,很少的程序有这种情况,目前测试到的乘scale_factor没问题
if scale_factor != 1f32 && (window_width == bitmap.bmWidth || bitmap.bmWidth == 0) {
new_width = (width as f32 * scale_factor) as i32;
new_height = (height as f32 * scale_factor) as i32;
}
// 内存中的HDC,使用 DeleteDC 函数释放
// https://learn.microsoft.com/zh-cn/windows/win32/api/wingdi/nf-wingdi-createcompatibledc
let box_hdc_mem = BoxHDC::new(CreateCompatibleDC(*box_hdc_window), None);
let box_h_bitmap = BoxHBITMAP::new(CreateCompatibleBitmap(*box_hdc_window, new_width, new_height));
let previous_object = SelectObject(*box_hdc_mem, *box_h_bitmap);
let mut is_success = false;
// https://webrtc.googlesource.com/src.git/+/refs/heads/main/modules/desktop_capture/win/window_capturer_win_gdi.cc#301
if get_os_major_version() >= 8 {
is_success = PrintWindow(hwnd, *box_hdc_mem, PRINT_WINDOW_FLAGS(2)).as_bool();
}
if !is_success && DwmIsCompositionEnabled()?.as_bool() {
is_success = PrintWindow(hwnd, *box_hdc_mem, PRINT_WINDOW_FLAGS(0)).as_bool();
}
if !is_success {
is_success = PrintWindow(hwnd, *box_hdc_mem, PRINT_WINDOW_FLAGS(3)).as_bool();
}
if !is_success {
// 并非所有设备都支持 StretchBlt 函数。 有关详细信息,请参阅 GetDeviceCaps。
// https://learn.microsoft.com/zh-cn/windows/win32/api/wingdi/nf-wingdi-stretchblt
SetStretchBltMode(*box_hdc_mem, COLORONCOLOR);
is_success = StretchBlt(
*box_hdc_mem,
0,
0,
new_width,
new_height,
*box_hdc_window,
0,
0,
width,
height,
SRCPAINT,
).as_bool();
if is_success {
SelectObject(*box_hdc_mem, previous_object);
// 这里使用new_width,否则图片被截取
return to_rgba_image(box_hdc_mem, box_h_bitmap, new_width, new_height);
}
}
if !is_success {
is_success = BitBlt(
*box_hdc_mem,
0,
0,
width,
height,
*box_hdc_window,
0,
0,
SRCCOPY,
)
.is_ok();
if is_success {
SelectObject(*box_hdc_mem, previous_object);
// 这里使用width,使用new_width会产生无意思的透明填充
return to_rgba_image(box_hdc_mem, box_h_bitmap, width, width);
}
}
if !is_success {
SelectObject(*box_hdc_mem, previous_object);
return Err(XCapError::new("Get data failed"));
}
// PrintWindow 的返回
to_rgba_image(box_hdc_mem, box_h_bitmap, new_width, new_height)
}
} |
发现BRGA转RGBA在一些特定情况下会执行几十秒。大量循环的调用win api且每次返回结果都是一样,导致大量耗时 https://github.com/nashaofu/xcap/blob/v0.0.10/src/windows/capture.rs#L70 例如测试一张 #[test]
fn test_api() {
let start = Instant::now();
let cn = 1920 * 1080;
for _ in 0..cn {
get_os_major_version();
}
println!("use time:{:?}", start.elapsed());
}
发现耗时80s, 改成如下会提升速度: let os_major_version = get_os_major_version();
for src in buffer.chunks_exact_mut(4) {
src.swap(0, 2);
// fix https://github.com/nashaofu/xcap/issues/92#issuecomment-1910014951
if src[3] == 0 && os_major_version < 8 {
src[3] = 255;
}
} |
有时间的话,你提交一个pr吧 |
|
No description provided.
The text was updated successfully, but these errors were encountered: