Python使用pywin32实现窗口截图

安装

pip install pywin32

示例代码

import ctypes
import numpy as np
import win32gui, win32ui, win32con
from PIL import Image
from time import sleep
from ctypes.wintypes import *
import os

"""功能
指定窗口名称进行窗口截图
generate_image_dataset() 保存图片到./images目录
get_window_size() 获取窗口大小
"""


class WindiwCapture:
    """窗口截图"""
    w = 0
    h = 0
    hwnd = None

    def __init__(self, window_name):
        self.hwnd = win32gui.FindWindow(None, window_name)  # 获取屏幕的窗口句柄
        if not self.hwnd:
            raise Exception('window {} not found'.format(window_name))

        left, top, right, bot = self.get_window_rect(self.hwnd)
        print(left, top, right, bot)
        self.w, self.h = right - left, bot - top

    def get_screenshot(self):
        # Get the window's device context
        hdc_window = win32gui.GetWindowDC(self.hwnd)
        hdc_mem = win32ui.CreateDCFromHandle(hdc_window)

        # Create a memory device context and a bitmap object
        mem_dc = hdc_mem.CreateCompatibleDC()

        # Create a bitmap object in memory
        bmp = win32ui.CreateBitmap()
        bmp.CreateCompatibleBitmap(hdc_mem, self.w, self.h)
        mem_dc.SelectObject(bmp)

        # Bit block transfer into our memory device context
        mem_dc.BitBlt((0, 0), (self.w, self.h), hdc_mem, (0, 0), win32con.SRCCOPY)

        # Convert the bitmap object to a PIL image
        bmp_info = bmp.GetInfo()
        bmp_str = bmp.GetBitmapBits(True)
        screenshot = Image.frombuffer(
            'RGB',
            (bmp_info['bmWidth'], bmp_info['bmHeight']),
            bmp_str, 'raw', 'BGRX', 0, 1
        )

        return screenshot

    def generate_image_dataset(self, i=None):
        """保存图片到当前路径"""
        if not os.path.exists('images'):
            os.mkdir('images')
        # i = 0
        while (True):
            # if i == 1:
            #     break
            img = self.get_screenshot()
            img.save(f"./images/img_{len(os.listdir('images'))}.jpg")
            sleep(1)  # 截图间隔 1 秒钟
            # i = i + 1

    def get_window_size(self):
        """用来获取窗口的宽度和高度"""
        return (self.w, self.h)

    def get_window_rect(self, hwnd):
        """
        自从vista系统开始,窗口有毛玻璃特效边框,而GetWindowRect并没有计算上这部分,所以获取的值会偏小
        Args:
            hwnd:窗口句柄
        Returns:
            left, top, right, bot
        """
        try:
            f = ctypes.windll.dwmapi.DwmGetWindowAttribute
        except WindowsError:
            f = None
        if f:
            rect = ctypes.wintypes.RECT()
            DWMWA_EXTENDED_FRAME_BOUNDS = 9
            f(ctypes.wintypes.HWND(hwnd),
              ctypes.wintypes.DWORD(DWMWA_EXTENDED_FRAME_BOUNDS),
              ctypes.byref(rect),
              ctypes.sizeof(rect)
              )
            return rect.left, rect.top, rect.right, rect.bottom


window_name = "MuMu模拟器12"
windcap = WindiwCapture(window_name)
windcap.generate_image_dataset()

运行后每隔1秒会截一张图,会保存到当前images路径。

img

posted @ 2024-05-23 00:13  Apostle浩  阅读(214)  评论(0编辑  收藏  举报