【问题标题】:PIL's ImageGrab is capturing at the wrong resolutionPIL 的 ImageGrab 以错误的分辨率捕获
【发布时间】:2014-08-23 23:28:34
【问题描述】:

我正在尝试使用此代码进行全屏 (1920 x 1080) 捕获。 保存的图像只有 1536 x 864。

解决方案:正如 Mark 在下面指出的,Windows 具有缩放功能,可以通过控制面板 > 显示进行更改(将其一直向下)。

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()

【问题讨论】:

  • 我无法在我的 1920x1200 显示器上重现您的问题,它抓住了整个问题。如果你打印im.size,你会得到什么?
  • (1536, 864)。我现在在一台 1920 x 1080 的笔记本电脑上,如果这会有所不同(这是原​​始分辨率)。
  • 您的桌面是否可以配置为该分辨率?转到显示属性并验证它。
  • 在 Windows 8.1 和 Mint 17 上绝对是 1920 x 1080。我确实注意到屏幕截图分辨率比我的原生分辨率小 20%。任何可能导致此问题的设置?
  • 有趣的是,窗口标题栏中的文字漂亮而清晰,而其余的文字看起来像是调整了大小。我怀疑 Windows 对软件撒谎,声明大小为 1536x864 并通过 DWM 缩放输出。如果您在显示属性中打开了任何缩放选项,请尝试将其关闭,看看它是否有任何变化。

标签: python python-imaging-library pillow


【解决方案1】:

如果您将显示设置设置为默认设置“较小”(100%) 设置以外的任何设置,Windows 将告诉您的应用程序渲染到较小的区域,然后在将结果放在桌面。显然 PIL 有一个由此设置引起的错误,捕获被裁剪为更小的尺寸而不是完整的桌面。解决方法是确保您的显示设置设置为 100%。

【讨论】:

  • 这个有什么消息吗?
  • @DanielReyhanian 我不知道,但有机会。 PIL 的开发停滞了很长时间,但后来 Pillow 被分叉了,此后发生了很多事情。
【解决方案2】:

我设法通过在

添加注册表项来解决这个问题

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:Marking Your Python Program as High DPI Aware Seemlessly Windows

【讨论】:

    【解决方案3】:

    我也遇到过同样的问题.. 在 4k 屏幕上运行试图捕获 1080p 应用程序。感谢这个thread,在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
    

    这解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多