Build improved screenshot API
Enhancement request:
tl;dr add beginner-friendly screenshot functionality with reasonable defaults
What should be added/changed?
The minimum
A function that grabs the image from the screen and immediately writes it to disk. It should meet the following requirements:
- Calling with zero arguments saves a screenshot to the current working directory with a reasonable time stamp format such as
"%windowname_%Y%m%d_%H%M_%S_%f.jpg" - Accepts the same optional bounds arguments as
get_image - Accepts an optional
save_pathargument that directly specifies the directory to save to or filename to use, overriding any formatting in the latter case - Accepts an optional
time_formatargument to override the default timestamp format.
Additional features
We may also want to add :
- A screenshot manager object that allows setting a default filename / timestamp format
- Queuing features that allow multiple screenshots to queued up before writing to disk at a specified time, such as on game exit to avoid slow disk access during gameplay
- Integration with the pyglet event system (example: take a screenshot whenever event or condition X happens)
- ~~Integrations with video format libraries to automatically assemble a movie of the screenshots~~ Moved to #1349
What would it help with?
- Reduce the number of tools users need to install or learn to get help
- Make the cross-platform experience much less confusing
- Make #1338 far easier to write
@einarf
It's possible to pipe each frame directly into ffmpeg instead. We don't have a wrapper for this, but it's not too difficult to make.
I noticed a previous commit removed ffmpeg as a windows dependency. Would we add it back in, or rely on a windows API for encoding?
I noticed a previous commit removed ffmpeg as a windows dependency. Would we add it back in, or rely on a windows API for encoding?
I think ffmpeg is something people would install separately. It's too much to bundle this for every platform.
It's too much to bundle this for every platform.
Which do you mean?
- ffmpeg is overkill for this problem
- managing ffmpeg as an included dependency creates too much work for the project
- including ffmpeg makes the install size too large
Streaming raw frames into ffmpeg is very useful. A lot of other libraries do this (Wasabi2D, moderngl-window, etc)
The last option is true: including ffmpeg makes the install size too large
It's something you install on the side.
I'm worried that recommending ffmpeg installation might be out of the reach of beginner users. Does the following sound like a reasonable plan?
- Write an initial version of #1338 per the original plan of recommending OS built-ins whenever possible
- Implement the first half of this ticket in the near-term future, adding mention of it to the screenshot doc as useful for advanced users or debugging
- Build the screenshot queuing & video capture extensions whenever time arises, marking them in the doc as experimental or for advanced users
ffmpeg would probably not be a beginner thing. Can just start with screenshot and expand later. We don't even have the video capture module yet.
Having a unified & streamlined cross-platform video capture technique would significantly simplify the screen capture doc. We might want to revisit the topic at a later point after considering minimal & maximal install versions some more.
Which would be preferable for default save paths?
- Use the current working directory as the default save location
- Auto-detect a platform-specific save directory for screenshots such as
~/Pictures/ - Make save directory a mandatory argument, do not allow defaults
Option 1 would be fastest, so I'm in favor of implementing it first.
1 is more than fine.
I noticed another issue: get_image uses the top left as the origin while the rest of the library uses the bottom left.
I see two general ways of addressing it:
- Leave
get_imagein the arcade namespace with the same signature and add new^(get|save)_screenshotfunctions consistent with the coordinate system used elsewhere. - Use the existing names (
get_image,get_pixel) and break compatibility.
Breaking compatibility seems like the better choice:
- The experimental examples call the method without arguments to capture the whole screen, as most users probably do.
- I haven't been able to come up with a legible alternate name for
get_pixel.
This seems like a good approach for now:
- Make
(get|save)_screenshotandget_pixelthe official screenshot functions, with the versions in thearcadenamespace calling those on theWindowreturned byget_window - Leave the current
get_(image|pixel)functions indraw_commandsas deprecated legacy functions for anyone who still wants to import them directly. - Update the programming guide and experimental examples accordingly.
It will make screenshots less confusing for all users and preserve the ability to use the non-OOP style used for teaching very young students.
We may want to wrap standard deprecation directives with warning boxes to mark get_image as deprecated. It seems that pyglet does something similar, but I haven't been able to find the exact place it defines that.