0

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.

Tiger-222
  • 6,677
  • 3
  • 47
  • 60
NewbieCoder
  • 105
  • 9

1 Answers1

0

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

Tiger-222
  • 6,677
  • 3
  • 47
  • 60
  • Hey man, it works when I lock the thread before doing `sct.grab()` and then releasing it. But it takes the same time as taking screenshots of blocks in a loop. Without the lock it still produces weird images and I still get the `gdi32.GetDIBits() failed.` error. Can you please tell me how to take screenshots of different blocks of the screen faster? – NewbieCoder Dec 31 '19 at 19:32
  • I am using Windows 10, py 3.7 if that helps and i posted the above comment after using the latest version of mss as you said (5.0.0) – NewbieCoder Dec 31 '19 at 19:46
  • In your code there is 2 calls to `sct.grab()`. Remove the second one, outside the lock. – Tiger-222 Jan 01 '20 at 00:42
  • Oh sorry that is a mistake when editing the code to post on stackoverflow. It has only one call under the lock and no calls outside in the actual code. Doing that takes the same time as taking multiple screenshots in a single threaded manner. Like [sct.grab(block) for block in blocks] – NewbieCoder Jan 01 '20 at 05:41
  • Can you check that [multiprocessing example](https://python-mss.readthedocs.io/examples.html#multiprocessing)? It may be helpful. Also, could you post the entire source code to help me reprocue the error? – Tiger-222 Jan 01 '20 at 10:28
  • Also, accessing to the `.rgb` attribute is expensive. With the full code I will be able to understand your needs and perhaps is there another approach to use. – Tiger-222 Jan 01 '20 at 10:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205188/discussion-between-newbiecoder-and-tiger-222). – NewbieCoder Jan 01 '20 at 14:25