feat: Take screenshots#759
Conversation
|
Very cool idea, would it be a good idea to add a visual indication that a screenshot was taken? |
Done |
|
Hey @el, sorry to nitpick but if you have the setting "Short power button click" set to "sleep", when trying to take screenshots the device goes to sleep if you're not careful to press both buttons exactly at the same time. Not sure that's a big deal, I still managed to take a few screenshots. |
lib/FsHelpers/FsHelpers.cpp
Outdated
|
|
||
| for (int y = 0; y < height; y++) { | ||
| const uint8_t* fbRow = framebuffer + (height - 1 - y) * fbRowSize; | ||
| if (file.write(fbRow, fbRowSize) != fbRowSize) { |
There was a problem hiding this comment.
An extra idea: you can rotate the image on-the-fly by allocating a row of pixels on the stack, then fill it.
The shorter edge of the screen is 480 pixels, with 1bpp that means 60 bytes to be allocated, we should always have enough memory for that.
There was a problem hiding this comment.
would you mind if I submit a patch here to rotate the bitmap on-the-fly?
There was a problem hiding this comment.
not at all, feel free to update
|
Can you please add |
src/main.cpp
Outdated
| return; | ||
| } | ||
|
|
||
| String filename_str = "/screenshots/screenshot-" + String(millis()) + ".bmp"; |
There was a problem hiding this comment.
At some point millis() wraps around. This results in the (incredibly small) chance of the same name being used twice, but more importantly the screenshots will potentially be out of order. Perhaps we can store the last 'screenshot number' as a uint16 in CrossPointState? That would give room for 65,535 screenshots before this becomes a problem.
There was a problem hiding this comment.
That would give room for 65,535 screenshots before this becomes a problem.
wrapped screenshot number + millis = infinite amount of screenshots
There was a problem hiding this comment.
I would have used date+time but x4 doesnt have an rtc :)
I think this is enough for now
I dont see how it would be useful, you mean take a screenshot after closing the menu? If so, I think we can do that after this is merged. |
lib/FsHelpers/FsHelpers.cpp
Outdated
|
|
||
| for (int y = 0; y < height; y++) { | ||
| const uint8_t* fbRow = framebuffer + (height - 1 - y) * fbRowSize; | ||
| if (file.write(fbRow, fbRowSize) != fbRowSize) { |
There was a problem hiding this comment.
would you mind if I submit a patch here to rotate the bitmap on-the-fly?
Yes after closing. So it is possible to do one handed. And more noticeable |
ngxson
left a comment
There was a problem hiding this comment.
I added the 90d ccw rotation in the last commit, should work fine now.
I think fixed rotation should already be enough for now, as most the time we use the default portrait orientation.
One thing to note: it would be nice if we can download the image from web UI. Currently I need to take out the SD card to get the image.
|
I’ve been testing this and found that setting the “Short power button click” to “sleep” actually conflicts with the combination for taking screenshots. And overall, I believe the current input manager isn’t very well-suited for reading multiple key combinations at once. Perhaps it would be better to add an action for taking screenshots to the reader menu? |
@Eloren1 has also suggested that change. I have implemented the Take Screenshot to the menu and also moved all logic to a new util. I have also increased sleep duration slightly to avoid conflicts. |
|
Thank you for the changes! I guess my question is, do we really need button combination for taking screenshots? Now that we have menu option, I am not sure it is that much required, considering we have to change existing logic to properly support it. @crosspoint-reader/firmware-maintainers what do you think |
I think it is still usefull, I imagine this feature could be used when
|
Absolutely, I am not talking about screenshot feature in general, it is useful, thank you for this btw. I'm just not sure if I like button overloading. But let's wait for other maintainers opinion |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a screenshot feature: hotkey (Power + Volume Down) and reader-menu trigger capture the framebuffer, save a rotated 1-bit BMP to /screenshots/, and show a brief on-screen confirmation. Also adds BMP header utilities and translations for the new menu label. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Main as main.cpp
participant ScreenshotUtil as ScreenshotUtil
participant Gfx as GfxRenderer
participant Storage as Storage
User->>Main: Press Power + Volume Down
Main->>ScreenshotUtil: takeScreenshot(renderer)
ScreenshotUtil->>Gfx: request framebuffer
Gfx-->>ScreenshotUtil: framebuffer bits
ScreenshotUtil->>Storage: ensure /screenshots/ exists
ScreenshotUtil->>ScreenshotUtil: rotate 90° CCW & build BMP header
ScreenshotUtil->>Storage: write BMP header + pixel data
ScreenshotUtil->>Gfx: draw temporary border confirmation
Storage-->>ScreenshotUtil: write success/failure
ScreenshotUtil-->>Main: return result
sequenceDiagram
actor User
participant Menu as EpubReaderMenuActivity
participant Reader as EpubReaderActivity
participant Renderer as GfxRenderer
participant ScreenshotUtil as ScreenshotUtil
participant Storage as Storage
User->>Menu: Open reader menu & select "Take screenshot"
Menu->>Reader: MenuAction::SCREENSHOT
Reader->>Reader: set pendingScreenshot
Reader->>Renderer: complete current render (holds render mutex)
Reader->>Reader: detect pendingScreenshot, clear flag
Reader->>ScreenshotUtil: takeScreenshot(renderer)
ScreenshotUtil->>Renderer: get framebuffer
ScreenshotUtil->>Storage: save BMP
ScreenshotUtil->>Renderer: show confirmation border
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
|
@el if I press screenshot combination while page is still rendering I get crash with this error. Might be related to issue Copilot suggested
|
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
|
@daveallie fyi |

Summary
screenshotsfolderAdditional Context
Example screenshots:
screenshot-6771.bmp
screenshot-14158.bmp
AI Usage
Did you use AI tools to help write this code? _** YES