Home > OS >  Taking a screenshot of a specific portion of the screen in Python
Taking a screenshot of a specific portion of the screen in Python

Time:05-28

I am currently working on a project where i need to take a 30x40 pixels screenshot from a specific area of my screen. This is not very hard to do as there are plenty of methods that do that.

The issue i have is that i need to take about 10 to 15 screenshots/second of the size i metioned. When i looked at some these methods that capture your screen, i have seen that when you give them parameters for a smaller selection, there's cropping involved. So a full screenshot is being taken, then the method crops it to the given size. That seems like a waste of resources if i'm only going to use 30x40 image, especially considering i will take thousands of screenshots. I might be wrong because i'm somewhat new to Python.

So my question is: Is there a method that ONLY captures a specific portion of your screen from the beginning, without capturing your whole screen, then "cutting" the desired section out of the big screenshot? I'm currently using this command im = pyautogui.screenshot(region=(0,0, 30, 40)). Thank you.

CodePudding user response:

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 as it screenshots are really extremely fast and therefore even able to capture frames from a video. 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"'
  • Related