Python:拍摄和保存屏幕截图的最快方法



我一直在努力想出一个脚本,让我每秒多次截取桌面的屏幕截图。我正在使用 Win10。

必:

from PIL import ImageGrab
import time
while True:
    im = ImageGrab.grab()
    fname = "dropfolder/%s.png" %int(time.time())
    im.save(fname,'PNG') 

结果 每张图像 1.01 秒。

PyScreeze (https://github.com/asweigart/pyscreeze):

import pyscreeze
import time
while True:
    fname = "dropfolder/%s.png" %int(time.time())
    x = pyscreeze.screenshot(fname)

结果 每张图像 1.00 秒。

赢32:

import win32gui
import win32ui 
import win32con
import time
w=1920 #res
h=1080 #res
while True:
    wDC = win32gui.GetWindowDC(0)
    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)
    fname = "dropfolder/%s.png" %int(time.time())
    dataBitMap.SaveBitmapFile(cDC, fname)
    dcObj.DeleteDC()
    cDC.DeleteDC()
    win32gui.ReleaseDC(0, wDC)
    win32gui.DeleteObject(dataBitMap.GetHandle())

结果 每张图像 1.01 秒。

然后我偶然发现了线程(在Windows上使用python截屏的最快方法),有人建议gtk会产生惊人的结果。

但是使用 gtk:

import gtk
import time
img_width = gtk.gdk.screen_width()
img_height = gtk.gdk.screen_height()
while True:
    screengrab = gtk.gdk.Pixbuf(
        gtk.gdk.COLORSPACE_RGB,
        False,
        8,
        img_width,
        img_height
    )
    fname = "dropfolder/%s.png" %int(time.time())
    screengrab.get_from_drawable(
        gtk.gdk.get_default_root_window(),
        gtk.gdk.colormap_get_system(),
        0, 0, 0, 0,
        img_width,
        img_height
        ).save(fname, 'png')

结果 每张图像 2.34 秒。

在我看来,我做错了什么,因为人们在 gtk 上取得了很好的成果。

有什么建议可以加快这个过程吗?

谢谢!

您的第一个解决方案应该是每秒给您多张图片。但问题是您将覆盖同一秒内发生的任何图片,即它们都具有相同的文件名。要解决此问题,您可以创建包含 10 秒的文件名,如下所示:

from PIL import ImageGrab
from datetime import datetime
while True:
    im = ImageGrab.grab()
    dt = datetime.now()
    fname = "pic_{}.{}.png".format(dt.strftime("%H%M_%S"), dt.microsecond // 100000)
    im.save(fname, 'png') 

在我的机器上,这给出了以下输出:

pic_1143_24.5.png
pic_1143_24.9.png
pic_1143_25.3.png
pic_1143_25.7.png
pic_1143_26.0.png
pic_1143_26.4.png
pic_1143_26.8.png
pic_1143_27.2.png

如果有人关心 2022 年: 您可以尝试我新创建的项目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()

我从自述文件中复制了基准部分的部分:

数码相机python-mssD3DShot
平均转数快238,7975,87118,36
标准开发1.250.54470.3224

此解决方案使用 d3dshot .

def d3dgrab(rect=(0, 0, 0, 0), spath=r".\pictures\cache\", sname="", title=""):
    """ take a screenshot by rect. """
    sname = sname if sname else time.strftime("%Y%m%d%H%M%S000.jpg", time.localtime())
    while os.path.isfile("%s%s" % (spath, sname)):
        sname = "%s%03d%s" % (sname[:-7], int(sname[-7:-4]) + 1, sname[-4:])
    xlen = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
    ylen = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
    assert 0 <= rect[0] <= xlen and 0 <= rect[2] <= xlen, ValueError("Illegal value of X coordination in rect: %s" % rect)
    assert 0 <= rect[1] <= ylen and 0 <= rect[3] <= ylen, ValueError("Illegal value of Y coordinatoin in rect: %s" % rect)
    if title:
        hdl = win32gui.FindWindow(None, title)
        if hdl != win32gui.GetForegroundWindow():
            win32gui.SetForegroundWindow(hdl)
        rect = win32gui.GetWindowRect(hdl)
    elif not sum(rect):
        rect = (0, 0, xlen, ylen)
    
    d = d3dshot.create(capture_output="numpy")
    return d.screenshot_to_disk(directory=spath, file_name=sname, region=rect)

我认为可以提供帮助

sname = sname if sname else time.strftime("%Y%m%d%H%M%S000.jpg", time.localtime())
while os.path.isfile("%s%s" % (spath, sname)):
    sname = "%s%03d%s" % (sname[:-7], int(sname[-7:-4]) + 1, sname[-4:])

这是我发现的最快的截屏方法。

相关内容

最新更新