Как получить окно или полноэкранный снимок экрана в Python 3k? (без PIL)

С python 3 я хотел бы получить дескриптор к другому окну (не часть моего приложения) таким образом, что я могу также:

a) непосредственно получите то окно как снимок экрана или

b) определите его положение и размер и получите его некоторый другой путь

В случае, если это важно, я использую Windows XP (редактирование: работы в Windows 7 также).

Я нашел это решение, но это не совсем, в чем я нуждаюсь, так как это - полный экран и что еще более важно, PIL насколько я знаю еще не поддерживает 3.x.

8
задан Community 23 May 2017 в 12:17
поделиться

2 ответа

Вот как это можно сделать с помощью PIL на win32. Учитывая дескриптор окна ( hwnd ), вам понадобятся только последние 4 строки кода. Предыдущее просто поиск окна с "firefox" в заголовке. Поскольку доступен исходный код PIL, вы должны иметь возможность ковыряться в методе ImageGrab.grab (bbox) и вычислять код Win32, который вам нужен, чтобы это произошло.

from PIL import ImageGrab
import win32gui

toplist, winlist = [], []
def enum_cb(hwnd, results):
    winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
win32gui.EnumWindows(enum_cb, toplist)

firefox = [(hwnd, title) for hwnd, title in winlist if 'firefox' in title.lower()]
# just grab the hwnd for first window matching firefox
firefox = firefox[0]
hwnd = firefox[0]

win32gui.SetForegroundWindow(hwnd)
bbox = win32gui.GetWindowRect(hwnd)
img = ImageGrab.grab(bbox)
img.show()
17
ответ дан 5 December 2019 в 05:44
поделиться

Арс дал мне все части. Я просто собираю эти части вместе для тех, кому нужно сделать скриншот в python 3.x. Далее мне нужно выяснить, как работать с растровой картой win32, не имея PIL, на который можно опереться.

Получение скриншота (передаем hwnd для окна, а не для полного экрана):

def screenshot(hwnd = None):
    import win32gui
    import win32ui
    import win32con
    from time import sleep
    if not hwnd:
        hwnd=win32gui.GetDesktopWindow()
    l,t,r,b=win32gui.GetWindowRect(hwnd)
    h=b-t
    w=r-l
    hDC = win32gui.GetWindowDC(hwnd)
    myDC=win32ui.CreateDCFromHandle(hDC)
    newDC=myDC.CreateCompatibleDC()

    myBitMap = win32ui.CreateBitmap()
    myBitMap.CreateCompatibleBitmap(myDC, w, h)

    newDC.SelectObject(myBitMap)

    win32gui.SetForegroundWindow(hwnd)
    sleep(.2) #lame way to allow screen to draw before taking shot
    newDC.BitBlt((0,0),(w, h) , myDC, (0,0), win32con.SRCCOPY)
    myBitMap.Paint(newDC)
    myBitMap.SaveBitmapFile(newDC,'c:\\tmp.bmp')

Получение хэндла окна по заголовку (для передачи в вышеуказанную функцию):

def _get_windows_bytitle(title_text, exact = False):
    def _window_callback(hwnd, all_windows):
        all_windows.append((hwnd, win32gui.GetWindowText(hwnd)))
    windows = []
    win32gui.EnumWindows(_window_callback, windows)
    if exact:
        return [hwnd for hwnd, title in windows if title_text == title]
    else:
        return [hwnd for hwnd, title in windows if title_text in title]
12
ответ дан 5 December 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: