Using mss with multithreading in python gives an error

1k Views Asked by At

I am using mss module in python to take screenshots of the whole screen. I have split the screen into separate blocks and I am taking screenshots of those specific blocks. Doing this in a loop takes so long and the time increases as the amount of blocks increases.

These are 5 blocks of 1920x1080 screen:

[{'top': 0, 'left': 0, 'width': 1920, 'height': 216}, {'top': 216, 'left': 0, 'width': 1920, 'height': 216}, {'top': 432, 'left': 0, 'width': 1920, 'height': 216}, {'top': 648, 'left': 0, 'width': 1920, 'height': 216}, {'top': 864, 'left': 0, 'width': 1920, 'height': 216}]

I used multithreading to do it but it produces a fuzzy image and takes screenshots of only some blocks not all (like some will be clear and others would be black).

I am doing all of these in an infinite loop and sending the images to the server.

def main(block):
    image = sct.grab(block).rgb
    # send image to server

with mss.mss() as sct:
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.map(main, blocks) 

The above code produced bad image (some blocks of the image are just black) so I tried doing this:

def threaded(func, args):
    threads = []

    for arg in args:
        thread = threading.Thread(target=func, args=(arg[0],arg[1],))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

def main(block, sct):
    with threading.Lock():
        image = sct.grab(block).rgb
    image = sct.grab(block).rgb
    # send image to server

with mss.mss() as sct:
    threaded(main, zip(blocks, [sct for i in range(len(blocks))]))

The above code gives this error:

Exception in thread Thread-165:
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "client.py", line 31, in main
    image = sct.grab(block).rgb
  File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\mss\windows.py", line 301, in grab
    raise ScreenShotError("gdi32.GetDIBits() failed.")
mss.exception.ScreenShotError: gdi32.GetDIBits() failed.

(this is in an infinite loop that's why thread count goes over 165)

Please help me with how to take screenshots using multithreading.

1

There are 1 best solutions below

7
On

I just published the version 5.0.0 that fixed several memory leaks. Could you have a try with that version?