ImageGrab PIL захватывает с неправильным разрешением

Я пытаюсь получить полноэкранный (1920 x 1080) захват с помощью этого кода. Однако сохраненные изображения-это только 1536 x 864.

решение: как Марк указал ниже Windows имеет масштабирование, которое можно изменить с помощью Панели Управления > Display (поверните его полностью вниз).

from PIL import ImageGrab
import os
import time

def screenGrab():
    # snapshot of screen
    im = ImageGrab.grab()
    # saves in current work directory with name based on time of pic
    im.save(os.getcwd() + 'full_snap__' + str(int(time.time()))
            + '.png', 'PNG')

def main():
    screenGrab()

if __name__ == '__main__':
    main()

3 ответов


Если у вас есть настройки дисплея, установленные на что-либо, кроме "меньшего" (100%) параметра, который является значением по умолчанию, Windows сообщит вашим приложениям отображать в меньшую область, а затем увеличить результаты, как он ставит его на рабочий стол. Очевидно, у PIL есть ошибка, вызванная этой настройкой, захват обрезается до меньшего размера, а не до полного рабочего стола. Обходной путь должен быть уверен, что ваши настройки дисплея установлены на 100%.


мне удается преодолеть эту проблему, добавив раздел реестра в

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

добавьте ключ с путем к вашему python.exe и pythonw.exe и в наборе значений HIGHDPIAWARE

вот так:

"C:\Users\Greg\Anaconda3\python.exe " = " HIGHDPIAWARE" "C:\Users\Greg\Anaconda3\pythonw.exe " = "HIGHDPIAWARE"

тогда все должно быть ОК :)

кредит этому scipt:маркировка вашей программы Python как высокой DPI Aware Seemlessly Windows


я столкнулся с той же проблемой.. запуск на экране 4k, пытаясь захватить приложение 1080p. Благодаря этому нить вызовите следующий код перед ImageGrab:

from ctypes import windll
user32 = windll.user32
user32.SetProcessDPIAware()

window_size = get_window_info()
last_time = time.time()
cv2.namedWindow("output", cv2.WINDOW_NORMAL)
while True:
    screen = np.array(ImageGrab.grab(bbox=window_size))
    # print('Frame took {} seconds'.format(time.time()-last_time))
    last_time = time.time()
    # new_screen = process_img(screen)
    imS = cv2.resize(screen, (960, 540))
    cv2.imshow('output', imS)
    # cv2.imshow('window',cv2.cvtColor(screen, cv2.COLOR_BGR2RGB))
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

это решило мою проблему.