Package: fast-ctypes-screenshots
Screenshots in record time - up to 2.5x faster than MSS (Multiple Screen Shots)The module provides classes for capturing screenshots in Windows operating systems. It offers four different classes: ScreenshotOfRegion, ScreenshotOfOneMonitor, ScreenshotOfAllMonitors, and ScreenshotOfWindow. These classes allow you to capture screenshots of specific regions, individual monitors, all monitors, or specific windows (even background windows) on the screen.For users who need to capture screenshots programmatically in their Python applications, this module can be of great interest. It provides a convenient and efficient way to capture screenshots using the Windows API, allowing for customization and flexibility in screenshot capturing.One notable advantage of this module is its speed. It utilizes direct access to the Windows API and minimizes overhead, resulting in faster screenshot capturing compared to other libraries like MSS (Multiple Screen Shots). This can be beneficial for applications that require real-time or high-frequency screenshot capturing.Furthermore, the module has minimal dependencies, making it lightweight and easy to integrate into existing projects. It relies on standard Windows libraries and ctypes for accessing the Windows API functions, reducing the need for additional external dependencies.pip install fast-ctypes-screenshotsTested against Windows 10 / Python 3.10 / AnacondaHow to use itfromtimeimporttimeimportcv2importnumpyasnpfromfast_ctypes_screenshotsimport(ScreenshotOfRegion,ScreenshotOfOneMonitor,ScreenshotOfAllMonitors,ScreenshotOfWindow,)# a simple benchmark functiondefshow_screenshot(screenshotiter,stop_at_frame=100,quitkey="q",show_screenshot=True):defshow_screenshotx():cv2.imshow("test",screenshot)ifcv2.waitKey(1)&0xFF==ord(quitkey):cv2.destroyAllWindows()returnFalsereturnTrueframecounter=0fps=0start_time=time()forscreenshotinscreenshotiter:ifstop_at_frame:ifframecounter>stop_at_frame:breakframecounter+=1ifshow_screenshot:sho=show_screenshotx()else:sho=Truefps+=1ifnotsho:breakprint(f"fast_ctypes_screenshots:{fps/(time()-start_time)}")cv2.destroyAllWindows()if__name__=="__main__":# Take one screenshot# ScreenshotOfWindow works even with background windowswithScreenshotOfWindow(hwnd=920542,client=False,ascontiguousarray=False)asscreenshots_window:img1=screenshots_window.screenshot_window()print(img1.shape)withScreenshotOfWindow(hwnd=920542,client=True,ascontiguousarray=False)asscreenshots_window:img2=screenshots_window.screenshot_window()print(img2.shape)# Screenshot of all monitorswithScreenshotOfAllMonitors(ascontiguousarray=False)asscreenshots_all_monitor:img4=screenshots_all_monitor.screenshot_monitors()print(img4.shape)# Screenshot of one monitor, starting at 0withScreenshotOfOneMonitor(monitor=0,ascontiguousarray=False)asscreenshots_monitor:img5=screenshots_monitor.screenshot_one_monitor()print(img5.shape)# x0=0, y0=40, x1=800, y1=680 -> rectanglewithScreenshotOfRegion(x0=0,y0=40,x1=800,y1=680,ascontiguousarray=False)asscreenshots_region:img6=screenshots_region.screenshot_region()print(img6.shape)######################################################################## Take many screenshots# from a window# screenshots_window is iterablewithScreenshotOfWindow(hwnd=920542,client=False,ascontiguousarray=False)asscreenshots_window:show_screenshot(screenshots_window,stop_at_frame=1500,quitkey="q",show_screenshot=True)withScreenshotOfWindow(hwnd=920542,client=True,ascontiguousarray=False)asscreenshots_window:show_screenshot(screenshots_window,stop_at_frame=1500,quitkey="q",show_screenshot=True)# from all monitors# screenshots_all_monitor is iterable toowithScreenshotOfAllMonitors(ascontiguousarray=False)asscreenshots_all_monitor:show_screenshot(screenshots_all_monitor,stop_at_frame=150,quitkey="q",show_screenshot=True,)# from one monitor# screenshots_monitor is iterable as wellwithScreenshotOfOneMonitor(monitor=0,ascontiguousarray=False)asscreenshots_monitor:show_screenshot(screenshots_monitor,stop_at_frame=150,quitkey="q",show_screenshot=True)withScreenshotOfRegion(x0=0,y0=40,x1=800,y1=680,ascontiguousarray=False)asscreenshots_region:show_screenshot(screenshots_region,stop_at_frame=150,quitkey="q",show_screenshot=True)Benchmark - MSS vs. fast-ctypes-screenshotsBenchmarkFPS One Screen - with cv2.imshow - MSSFPS One Screen - with cv2.imshow - fast_ctypes_screenshotsFPS One Screen - without cv2.imshow - MSSFPS One Screen - without cv2.imshow - fast_ctypes_screenshots1 screen - 1920x108014.57063782993409629.7534636665589629.04046029324538532.074495247216842 screens - 3840x108010.88583964436146618.84387152609732817.1983689714378124.268109622214084region - 2800x96013.5424711029326928.72281998325628321.34239389280659829.528899151991656# MSS https://python-mss.readthedocs.io/ vs. fast_ctypes_screenshots# The code for the benchmarkimportmssprint("\n\n-------------------------Benchmark - 1 screen - 1920x1080")fps=0last_time=time()withmss.mss()assct:for_inrange(150):sct_img=sct.grab(sct.monitors[1])img=np.array(sct_img)cv2.imshow("test",img)fps+=1ifcv2.waitKey(25)&0xFF==ord("q"):cv2.destroyAllWindows()breakprint(f"\n\n\nFPS One Screen - with cv2.imshow - MSS:{fps/(time()-last_time)}\n")print("FPS One Screen - with cv2.imshow - ",end=" ")cv2.destroyAllWindows()withScreenshotOfOneMonitor(monitor=0,ascontiguousarray=False)asscreenshots_monitor:show_screenshot(screenshots_monitor,stop_at_frame=150,quitkey="q",show_screenshot=True)cv2.destroyAllWindows()#########################################################fps=0last_time=time()withmss.mss()assct:for_inrange(150):sct_img=sct.grab(sct.monitors[1])img=np.array(sct_img)fps+=1print(f"\n\n\nFPS One Screen - without cv2.imshow - MSS:{fps/(time()-last_time)}\n")print("FPS One Screen - without cv2.imshow - ",end=" ")withScreenshotOfOneMonitor(monitor=0,ascontiguousarray=False)asscreenshots_monitor:show_screenshot(screenshots_monitor,stop_at_frame=150,quitkey="q",show_screenshot=False)cv2.destroyAllWindows()#########################################################print("\n\n-------------------------Benchmark - 2 screens - 3840x1080")fps=0last_time=time()withmss.mss()assct:for_inrange(100):sct_img=sct.grab(sct.monitors[0])img=np.array(sct_img)cv2.imshow("test",img)fps+=1ifcv2.waitKey(25)&0xFF==ord("q"):cv2.destroyAllWindows()breakprint(f"\n\n\nFPS All screens - with cv2.imshow - MSS:{fps/(time()-last_time)}\n")cv2.destroyAllWindows()print("FPS All screens - with cv2.imshow - ",end=" ")withScreenshotOfAllMonitors(ascontiguousarray=False)asscreenshots_region:show_screenshot(screenshots_region,stop_at_frame=100,quitkey="q",show_screenshot=True)cv2.destroyAllWindows()#########################################################fps=0last_time=time()withmss.mss()assct:for_inrange(100):sct_img=sct.grab(sct.monitors[0])img=np.array(sct_img)fps+=1print(f"\n\n\nFPS All screens - without cv2.imshow - MSS:{fps/(time()-last_time)}\n")print("FPS All screens - without cv2.imshow - ",end=" ")withScreenshotOfAllMonitors(ascontiguousarray=False)asscreenshots_region:show_screenshot(screenshots_region,stop_at_frame=100,quitkey="q",show_screenshot=False)#########################################################print("\n\n-------------------------Benchmark - region - 2800x960")fps=0last_time=time()monitor={"top":40,"left":0,"width":2800,"height":960}withmss.mss()assct:for_inrange(150):img=np.array(sct.grab(monitor))cv2.imshow("test",img)fps+=1ifcv2.waitKey(25)&0xFF==ord("q"):cv2.destroyAllWindows()breakprint(f"\n\n\nFPS Region - with cv2.imshow - MSS:{fps/(time()-last_time)}\n")print("FPS Region - with cv2.imshow - ",end=" ")cv2.destroyAllWindows()withScreenshotOfRegion(x0=0,y0=40,x1=2800,y1=1000,ascontiguousarray=False)asscreenshots_region:show_screenshot(screenshots_region,stop_at_frame=150,quitkey="q",show_screenshot=True)cv2.destroyAllWindows()#########################################################fps=0last_time=time()monitor={"top":40,"left":0,"width":2800,"height":960}withmss.mss()assct:for_inrange(150):img=np.array(sct.grab(monitor))fps+=1print(f"\n\n\nFPS Region - without cv2.imshow - MSS:{fps/(time()-last_time)}\n")print("FPS Region - without cv2.imshow: ",end=" ")withScreenshotOfRegion(x0=0,y0=40,x1=2800,y1=1000,ascontiguousarray=False)asscreenshots_region:show_screenshot(screenshots_region,stop_at_frame=150,quitkey="q",show_screenshot=False)