Fastest way to take a screenshot with python on windows
You could use win32 APIs directly .
First give the focus to the App that you want to take screenshot of.
link textWin32 API can help with the screenshot:
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())
Python: Fastest way to take and save screenshots
Your first solution should be giving you more than one picture per second. The problem though is that you will be overwriting any pictures that occur within the same second, i.e. they will all have the same filename. To get around this you could create filenames that include 10ths of a second as follows:
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')
On my machine, this gave the following output:
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
What is the most efficient way to capture screen in python using modules eg PIL or cv2? because It takes up a lot of ram
You can use mss
which is an "An ultra fast cross-platform multiple screenshots module in pure python".
For example:
import time
import cv2
import numpy as np
from mss import mss
start_time = time.time()
mon = {'top': 200, 'left': 200, 'width': 200, 'height': 200}
with mss() as sct:
while True:
last_time = time.time()
img = sct.grab(mon)
print('The loop took: {0}'.format(time.time()-last_time))
cv2.imshow('test', np.array(img))
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
Result:
The loop took: 0.024120092391967773
Output:
The result is faster 100x than your current result.
Fast screenshot of a small part of the screen in Python
The Python mss module ( https://github.com/BoboTiG/python-mss , https://python-mss.readthedocs.io/examples.html ), an ultra fast cross-platform multiple screenshots module in pure Python using ctypes ( where MSS stands for Multiple Screen Shots ), is what you are looking for. The screenshots are fast enough to capture frames from a video and the smaller the part of the screen to grab the faster the capture (so there is apparently no cropping involved ). Check it out. mss.mss().grab()
outperforms by far PIL.ImageGrab.grab()
. Below a code example showing how to get the data of the screenshot pixels (allows to detect changes):
import mss
from time import perf_counter as T
left = 0
right = 2
top = 0
btm = 2
with mss.mss() as sct:
# parameter for sct.grab() can be:
monitor = sct.monitors[1] # entire screen
bbox = (left, top, right, btm) # screen part to capture
sT=T()
sct_im = sct.grab(bbox) # type: <class 'mss.screenshot.ScreenShot'>
eT=T();print(" >", eT-sT) # > 0.0003100260073551908
print(len(sct_im.raw), sct_im.raw)
# 16 bytearray(b'-12\xff\x02DU\xff-12\xff"S_\xff')
print(len(sct_im.rgb), sct_im.rgb)
# 12 b'21-UD\x0221-_S"'
Take screenshots **quickly** from python
If you want fast screenshots, you must use a lower level API, like DirectX or GTK. There are Python wrappers for those, like DirectPython and PyGTK. Some samples I've found follow:
PyGTK sample
Windows and DirectX samples
Related Topics
How to Get Last Items of a List in Python
Imports in _Init_.Py and 'Import As' Statement
Matplotlib: How to Plot Images Instead of Points
Concatenate a List of Pandas Dataframes Together
What Do I Do When I Need a Self Referential Dictionary
How to Run a Function Periodically in Python
Best Way to Check Function Arguments
A Very Simple Multithreading Parallel Url Fetching (Without Queue)
Forced Naming of Parameters in Python
Prevent Pandas from Interpreting 'Na' as Nan in a String
Python Filter List of Dictionaries Based on Key Value
How Does the Key Argument in Python's Sorted Function Work
Getting Rid of Console Output When Freezing Python Programs Using Pyinstaller
How to Convert Strings in a Pandas Data Frame to a 'Date' Data Type
Creating Dynamically Named Variables from User Input
How to Implement Option Buttons and Change the Button Color in Pygame