【问题标题】:Fastest way to take a screenshot with python on windows在 Windows 上使用 python 截屏的最快方法
【发布时间】:2010-08-27 16:03:31
【问题描述】:

在 Windows 上截屏最快的方法是什么? PIL.ImageGrab 相当慢.. 对同一个小窗口进行 30 个屏幕截图需要 4-5 秒。截取整个桌面的屏幕截图甚至更慢。

【问题讨论】:

  • 听起来你真正想要的是屏幕视频,就像 Sourceforge 上的 CamStudio。用例是什么?
  • winterbells上获得最高分=P
  • 刚刚给 Winterbells 玩了一场,令人惊讶地上瘾

标签: python windows screenshot


【解决方案1】:

您可以直接使用 win32 API。

  1. 首先将焦点放在您要截屏的应用上。 link text

  2. Win32 API可以帮忙截图:

import win32gui
import win32ui
import win32con

w = 1920 # set this
h = 1080 # set this
bmpfilenamename = "out.bmp" #set this

hwnd = win32gui.FindWindow(None, windowname)
wDC = win32gui.GetWindowDC(hwnd)
dcObj=win32ui.CreateDCFromHandle(wDC)
cDC=dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0,0),(w, h) , dcObj, (0,0), win32con.SRCCOPY)
dataBitMap.SaveBitmapFile(cDC, bmpfilenamename)

# Free Resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())

【讨论】:

  • 非常重要,因为这最近让我大吃一惊:您必须删除/释放由此创建的所有 DC,否则在拍摄约 90 张图像后,您将无法再这样做。在这种情况下,dcObj.DeleteDC(); cDC.DeleteDC(); win32gui.ReleaseDC(hwnd, wDC)
  • 查看此脚本了解更多详情:bytes.com/topic/python/answers/…
  • 作为@Claudiu 评论的后续(正如他所说,这确实是必要的),我发现win32gui.DeleteObject(dataBitMap.GetHandle()) 也是必要的。我已经编辑了答案以包括两个 cmets。
  • 这比 pyscreenshot 和 PIL 快多了,谢谢!
  • windowname 在哪里定义和/或它应该是什么?
【解决方案2】:

刚刚发现如何使用 gtk 来实现。到目前为止似乎最快:

def image_grab_gtk(window):
    left, top, right, bot = get_rect(window)
    w = right - left
    h = bot - top

    s = gtk.gdk.Pixbuf(
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h)

    s.get_from_drawable(
        gtk.gdk.get_default_root_window(),
        gtk.gdk.colormap_get_system(),
        left, top, 0, 0, w, h )

    final = Image.frombuffer(
        "RGB",
        (w, h),
        s.get_pixels(),
        "raw",
        "RGB",
        s.get_rowstride(), 1)
    return final

在不转换为PIL 图像的情况下,它在我的测试用例中比 PIL 快 8 倍。通过转换,它仍然快 2.7 倍。

【讨论】:

    【解决方案3】:

    你可以使用包mss:

    保存截图到图片文件

    import mss
    
    with mss.mss() as sct:
        filename = sct.shot(output="output.png")
    

    获取截图的numpy表示

    import mss
    import numpy as np
    
    with mss.mss() as sct:
        monitor = {"top": 160, "left": 160, "width": 160, "height": 135}
        img_array = np.array(sct.grab(monitor))
        # Do whatever you want...
    

    【讨论】:

    • 如果您检查过,与其他选项相比,这有多快? TY 分享,无论如何!
    • 我在 2k 显示器上达到 40+ fps,4k 大约 20+ fps。
    • 分享!使用 1440p 的其他方法我得到了 13fps,但使用 mss 我能够达到 20fps。这肯定很快:)
    猜你喜欢
    • 1970-01-01
    • 2011-06-25
    • 2011-07-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    相关资源
    最近更新 更多