开发者

Python使用mss获取窗口图片的方法

目录
  • 1. 安装依赖库(需在本地执行)
  • 2. 使用mss获取窗口图片的详细步骤
    • 步骤1:获取窗口句柄及精确坐标
    • 步骤2:配置mss截图参数
  • 3. 关键问题处理
    • 问题1:坐标偏移(如标题栏/边框)
    • 问题2:DPI缩放导致尺寸错误
    • 问题3:多显示器坐标系差异
  • 4. 完整修正代码
    • 5. 跨平台适配建议
      • 6. 验证与调试技巧

        您在使用mss时遇到的ModuleNotFoundError表明当前环境未安装该库。以下是完整解决方案,包含安装指导、代码逻辑详解及常见问题处理:

        1. 安装依赖库(需在本地执行)

        pip install mss pywin32
        

        2. 使用mss获取窗口图片的详细步骤

        步骤1:获取窗口句柄及精确坐标

        import win32gui
        from mss import mss
        
        # 获取窗口句柄
        hwnd = win32gui.Findwindow(None, "记事本")  # 替换为实际窗口标题
        if hwnd == 0:
            raise Exception("未找到目标窗口")
        
        # 获取窗口客户区坐标(排除标题栏/边框)
        left, top, right, bot = win32gui.GetClientRect(hwnd)
        win32gui.ClientToScreen(hwnd, (left, top))  # 转换为屏幕绝对坐标
        

        步骤2:配置mss截图参数

        with mss() as sct:
            # 定义截图区域(精确到客户区)
            monitor = {
                "left": left,
                "top": top,
                "width": right - left,
                "height": bot - top
            }
            
            # 捕获屏幕区域
            sct_img = sct.grab(monitor)
            
            # 保存为PNG(自动处理BGRA转RGB)
            sct_img = sct_img.convert("RGB")
            sct_img.save("window_mss.png")
        

        3. 关键问题处理

        问题1:坐标偏移(如标题栏/边框)

        • 原因GetWindowRect返回的是窗口外部矩形,包含非客户区。
        • 解决:使用GetClientRect + ClientToScreen组合获取客户区绝对坐标,确保截图仅包含内容区域。

        问题2:DPI缩放导致尺寸错误

        检测方法

        from ctypes import windll
        dpi = windll.user32.GetDpiFojavascriptrWindow(hwnd)
        scale = dpi / 96.0  # 96为基准DPI
        adjusted_width = int((right - left) * scale)
        

        处理:在monitor字典中使用调整后的尺寸。

        问题3:多显示器坐标系差异

        • 验证:使用ctypes.windll.user32.GetMonitorInfo获取显示器物理范围。
        • 示例
        monitor_info = {}
        ctypes.windll.user32.GetMonitorInfoA(ctypes.windll.user32.MonitorFromWindow(hwnd, 1), ctypes.byref(monitor_info))
        print("显示器工作区:", monitor_info["rcWork"])
        

        4. 完整修正代码

        import win32gui
        from mss import mss
        import ctypes
        
        # 获取窗口句柄
        hwnd = win32gui.FindWindow(None, "记事本")
        if hwnd == 0:
            raise Exception("未找到记事本窗口")
        
        # 获取客户区坐标
        left, top, right, bot = win32gui.GetClientRect(hwnd)
        win32gui.ClientToScreen(hwnd, (left, top))
        
        # 处理DPI缩放
        dpi = ctypes.windll.user32.GetDpiForWindow(hwnd)
        scale = dpi / 96.0
        adjusted_left = int(left * scale)
        adjusted_top = int(top * scale)
        width = int((right - left) * scale)
        height = int((bot - top) * scale)
        
        # 使用mss截图
        with mss() as sct:
            monitor = {
                "left": adjusted_left,
                "top": adjusted_top,
                "widthttp://www.devze.comh": wi编程dth,
                "height": height
            }
            sct_img = sct.grab(monitor)
            sct_img = sct_img.convert("RGB")  # 转换颜色格式
            sct_img.save("corrected_window.png")
        
        print("截图已保存,尺寸:{}x{}".format(width, height))
        

        5. 跨平台适配建议

        MACOS/linux:使用QuartzXlib替代win32gui,逻辑类似:http://www.devze.com

        # macOS示例(通过Quartz获取窗口ID)
        from Quartz import CGWindowListCopyWindowInfo
        Windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll)
        target_window = [w for w in windows if "记事本" in w.get("kCGWindowName", "")][编程0]
        bounds = target_window["kCGWindowBounds"]
        

        6. 验证与调试技巧

        • 坐标验证:使用print(monitor)输出截图区域坐标,与实际窗口对比。
        • 边界测试:在纯色桌面背景下测试,检查截图边角是否与窗口边缘对齐。
        • 性能优化:对于频繁截图场景,缓存窗口句柄和DPI值以减少重复计算。

        通过上述方法,可彻底解决窗口截图的位置偏差问题。如仍遇异常,建议使用pygetwindow库辅助验证窗口坐标,或通过pywin32GetWindowplacement进一步调试窗口状态。

        到此这篇关于python使用mss获取窗口图片的方法的文章就介绍到这了,更多相关Python mss获取窗口图片内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜