简体   繁体   English

"ImageGrab.grab() 方法太慢"

[英]ImageGrab.grab() method is too slow

So i need to get a bunch of screenshots every second, like 5. I am using it to program a bot for a game.所以我需要每秒获取一堆屏幕截图,比如 5。我正在使用它来为游戏编写机器人程序。 However imagegrab method takes like 0.3 seconds, which is terribly slow for me.然而 imagegrab 方法需要 0.3 秒,这对我来说非常慢。 Even after specifying the bbox values it still takes like 0.3 seconds.即使在指定 bbox 值之后,它仍然需要 0.3 秒。 I think should mention that I am on a mac.我想应该提到我在Mac上。 Is there a better way for me有没有更好的方法适合我

I even tried the os.system("screencapture filename.png") which has a runtime of 0.15-0.2 seconds which is nice but I want to go faster.我什至尝试了运行时间为 0.15-0.2 秒的os.system("screencapture filename.png") ,这很好,但我想更快。

Another solution is to use Python MSS<\/a> .另一种解决方案是使用Python MSS<\/a> 。

from mss import mss
from PIL import Image

def capture_screenshot():
    # Capture entire screen
    with mss() as sct:
        monitor = sct.monitors[1]
        sct_img = sct.grab(monitor)
        # Convert to PIL/Pillow Image
        return Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')

img = capture_screenshot()
img.show()

Question : what could preform better than ImageGrab.grab() on a Mac问题:在 Mac 上,有什么比 ImageGrab.grab() 更好的表现?<\/h1>

I did a test between mss, pil, and pyscreenshot and measured the average time it took to take a various sized image grabs and reported the time in milliseconds.我在 mss、pil 和 pyscreenshot 之间进行了测试,并测量了抓取各种大小的图像所需的平均时间,并以毫秒为单位报告了时间。

Answer回答<\/h1>

It appears that mss<\/a> far exceeds the others on a mac.似乎mss<\/a>在 mac 上远远超过其他人。 To capture a 800x400 slice of the screen mms takes 15ms whereas the other two take 300-400ms.要捕获 800x400 的屏幕切片,mms 需要 15ms,而其他两个需要 300-400ms。 That's the difference between 66fps for mms or 3fps for the other two.这就是 mms 的 66fps 或其他两个 3fps 之间的区别。

Code代码<\/h1>
# !pip install image # !pip install opencv-python # !pip install pyscreenshot import numpy as np from time import time resolutions = [ (0, 0, 100,100),(0, 0, 200,100), (0, 0, 200,200),(0, 0, 400,200), (0, 0, 400,400),(0, 0, 800,400) ] import numpy as np import pyscreenshot as ImageGrab import cv2 def show(nparray): import cv2 cv2.imshow('window',cv2.cvtColor(nparray, cv2.COLOR_BGR2RGB)) # key controls in a displayed window # if cv2.waitKey(25) & 0xFF == ord('q'): # cv2.destroyAllWindows() def mss_test(shape) : average = time() import mss sct = mss.mss() mon = {"top": shape[0], "left": shape[1], "width": shape[2]-shape[1], "height": shape[3]-shape[0]} for _ in range(5): printscreen = np.asarray(sct.grab(mon)) average_ms = int(1000*(time()-average)\/5.) return average_ms, printscreen.shape def pil_test(shape) : average = time() from PIL import ImageGrab for _ in range(5): printscreen = np.array(ImageGrab.grab(bbox=shape)) average_ms = int(1000*(time()-average)\/5.) return average_ms, printscreen.shape def pyscreenshot_test(shape): average = time() import pyscreenshot as ImageGrab for _ in range(5): printscreen = np.asarray( ImageGrab.grab(bbox=shape) ) average_ms = int(1000*(time()-average)\/5.) return average_ms, printscreen.shape named_function_pair = zip("mss_test,pil_test,pyscreenshot_test".split(","), [mss_test,pil_test,pyscreenshot_test]) for name,function in named_function_pair: results = [ function(res) for res in resolutions ] print("Speed results for using",name) for res,result in zip(resolutions,results) : speed,shape = result print(res,"took",speed,"ms, produced shaped",shape)<\/code><\/pre>

Output输出<\/h1>
Speed results for using mss_test (0, 0, 100, 100) took 7 ms, produced shaped (200, 200, 4) (0, 0, 200, 100) took 4 ms, produced shaped (200, 400, 4) (0, 0, 200, 200) took 5 ms, produced shaped (400, 400, 4) (0, 0, 400, 200) took 6 ms, produced shaped (400, 800, 4) (0, 0, 400, 400) took 9 ms, produced shaped (800, 800, 4) (0, 0, 800, 400) took 15 ms, produced shaped (800, 1600, 4) Speed results for using pil_test (0, 0, 100, 100) took 313 ms, produced shaped (100, 100, 4) (0, 0, 200, 100) took 321 ms, produced shaped (100, 200, 4) (0, 0, 200, 200) took 334 ms, produced shaped (200, 200, 4) (0, 0, 400, 200) took 328 ms, produced shaped (200, 400, 4) (0, 0, 400, 400) took 321 ms, produced shaped (400, 400, 4) (0, 0, 800, 400) took 320 ms, produced shaped (400, 800, 4) Speed results for using pyscreenshot_test (0, 0, 100, 100) took 85 ms, produced shaped (200, 200, 4) (0, 0, 200, 100) took 101 ms, produced shaped (200, 400, 4) (0, 0, 200, 200) took 122 ms, produced shaped (400, 400, 4) (0, 0, 400, 200) took 163 ms, produced shaped (400, 800, 4) (0, 0, 400, 400) took 236 ms, produced shaped (800, 800, 4) (0, 0, 800, 400) took 400 ms, produced shaped (800, 1600, 4)<\/code><\/pre>

Further Observations进一步的观察<\/h1>

Although all three libraries were sent identical screen areas to grab, both mss and pyscreenshot grabbed physical pixels of the mac screen where as pil grabbed the logical pixels.尽管所有三个库都发送了相同的屏幕区域进行抓取,但 mss 和 pyscreenshot 都抓取了 mac 屏幕的物理像素,而 pil 抓取了逻辑像素。 This only happens if you have your Mac display resolution turned down from its highest resolution.仅当您将 Mac 显示分辨率从其最高分辨率调低时才会发生这种情况。 In my case I have a retinal display set to "balanced" which means that each logical pixel is actually 2x2 physical pixels.在我的情况下,我将视网膜显示器设置为“平衡”,这意味着每个逻辑像素实际上是 2x2 物理像素。

"

So how I got it working for me is by using所以我如何让它为我工作是通过使用

os.system("screencapture -R0,0,100,100 filename.png")
im = Image.open("filename.png")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ImageGrab.grab() 的时序 function - Timing of ImageGrab.grab() function _tkinter.TclError:图像“...”不存在 _ImageGrab.grab() - _tkinter.TclError: image “…” doesn't exist _ ImageGrab.grab() ImageGrab.grab() 在第一个屏幕上运行代码时的第二个屏幕 - ImageGrab.grab() the second screen while running code on the first screen RGB是从ImageGrab获取的吗。grab()。load()是数组还是字符串 - Is RGB taken from ImageGrab.grab().load() is in array or string 使用 ImageGrab.grab() 时发生的奇怪事情 - Weird things happening when using ImageGrab.grab() ImageGrab.grab(bbox)和Image.getpixel()一起使用 - ImageGrab.grab(bbox) and Image.getpixel() Used together ImageGrab.grab(bbox()) 不返回 RGB 值 - ImageGrab.grab(bbox()) doesn't return RGB values ImageGrab.grab 不是获取 tkinter 窗口的小部件,而是获取其下的屏幕区域 - ImageGrab.grab not get widget of tkinter window, but screen area under it 如何使用ImageGrab.grab()。load()函数或任何其他函数获取像素更新? - How to use the ImageGrab.grab().load() function or any other function to get pixel updates? 屏幕截图(PIL)Win10上的ImageGrab.grab / BitBlt仅返回背景吗? - Screenshot (PIL)ImageGrab.grab / BitBlt on Win10 only return the Background?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM