autopy
autopy copied to clipboard
Screenshots sometimes outdated when cropping in the same Python line
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