autopy icon indicating copy to clipboard operation
autopy copied to clipboard

Screenshots sometimes outdated when cropping in the same Python line

Open Ghostkeeper opened this issue 4 years ago • 0 comments

Yesterday I found something interesting that seems to be a bug in Autopy. I have the following script, trimmed down to just what's necessary to reproduce the bug, to convert slides for a presentation into images to be used in a video:

import autopy
import time
num_slides = 123
for slide_nr in range(num_slides):
    b = autopy.bitmap.capture_screen().cropped(((72, 138), (1920, 1080)))
    b.save(f"screenshots/{slide_nr}.png")
    # Some more stuff down here.
    time.sleep(1)

To reproduce, you also need to have something moving in that region of the screen, like a video (in my case I had slides progressing).

Then as I ran that, I found that some screenshots were duplicate. Not all of them, but like 1 in 10 screenshots were a duplicate of the previous screenshot. And then the next screenshots were up to speed again; it skipped over one of the slides.

I tried a few things that didn't fix the problem:

  • Added more delays to give the presentation software time to catch up.
  • Removed transitions from the slides.
  • Use smooth mouse movements to maybe trigger more screen updates.
  • Added delay between the screenshot and the save, in case the screenshot would be processed asynchronously or something.
  • Saved the screenshots in a list rather than re-using the same b variable, in case the variable somehow didn't get updated.
  • Taking two screenshots rather than one. Although I still used one .save() call.

None of this worked. Then I tried to put the cropped() call on a new line:

import autopy
import time
num_slides = 123
for slide_nr in range(num_slides):
    b = autopy.bitmap.capture_screen()
    b = b.cropped(((72, 138), (1920, 1080)))
    b.save(f"screenshots/{slide_nr}.png")
    # Some more stuff down here.
    time.sleep(1)

And the problem had disappeared.

To me this sounds like there is something weird going on with the memory there. Perhaps the single-line command deletes the bitmap sometimes, while it's still being cropped? Perhaps the crop needs to alter the pointer to the bitmap due to a reallocation and something accidentally gets released then due to reference counting? I have no experience with Rust so it's hard to tell what could be the problem.

Here is some information about my computer in case that's relevant:

  • CPU: AMD Ryzen 3900X
  • GPU: NVidia GTX 2070 Windforce
  • Screen resolution: 5120x1440 (just a single screen)
  • OS: Ubuntu 20.04
  • XTest: libxtst6 version 2:1.2.3-1, installed through apt.
  • Autopy version: 4.0.0, installed through pip.
  • Python version: 3.8.2

Ghostkeeper avatar May 23 '20 22:05 Ghostkeeper