添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在Windows上用Python进行截图的最快方法

18 人关注

在windows上截图的最快方法是什么?替换代码0】是相当慢的。对同一个小窗口进行30次截图需要4-5秒。给整个桌面截图就更慢了。

3 个评论
听起来你真正想要的是屏幕视频,就像Sourceforge的CamStudio一样。你的用途是什么?
to get the highest score ever on winterbells =P
刚刚玩了一下Winterbells,令人惊讶的是它很上瘾。
python
windows
screenshot
Claudiu
Claudiu
发布于 2010-08-28
4 个回答
pyfunc
pyfunc
发布于 2021-10-25
已采纳
0 人赞同

你可以直接使用win32 APIs。

  • 首先,将焦点放在你想截图的应用程序上。 link text

  • 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()) 也是必要的。 我已经编辑了答案,以包括这两条评论。
    这比pyscreenshot和PIL要快得多,谢谢!
    替换代码0】在哪里定义和/或它应该是什么?
    Claudiu
    Claudiu
    发布于 2021-10-25
    0 人赞同

    刚刚发现了如何用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倍的速度。

    ra1n
    ra1n
    发布于 2021-10-25
    0 人赞同

    你可以试试我新创建的项目 DXcam :我认为就原始速度而言,它是目前最快的(在python中,而且没有深入到兔子洞)。它最初是为FPS游戏的深度学习管道创建的,在那里你得到的FPS越高越好。另外,我(正在努力)把它设计成用户友好型的。 对于截图,只需做

    import dxcam
    camera = dxcam.create()
    frame = camera.grab()  # full screen
    frame = camera.grab(region=(left, top, right, bottom))  # region
    

    用于屏幕捕捉。

    camera.start(target_fps=60)  # threaded
    for i in range(1000):
        image = camera.get_latest_frame()  # Will block until new frame available
    camera.stop()
    

    我复制了readme中基准部分的内容。

    基准测试是在我的240hz显示器上进行的5次试验,与显示器同步的恒定240hz渲染率(使用blurbuster ufo测试)。

    你可以在这里阅读更多细节。https://github.com/ra1nty/DXcam

    这是一个有趣的库!请把它放在PyPI主库中。他们的测试库只是为了测试。
    就我的应用而言,这比mss慢得多,但保证每一帧都是新的,这很好。
    SeanCheey
    SeanCheey
    发布于 2021-10-25
    0 人赞同

    你可以使用包 mss :

    Save screenshot to image file

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

    Get the numpy representation of screenshot

    import mss
    import numpy as np