feat: Take screenshots (#759)
## Summary * **What is the goal of this PR?** Implements a take-screenshot feature * **What changes are included?** - Quick press Power button and Down button at the same time to take a screenshot - Screenshots are saved in `screenshots` folder ## Additional Context - Currently it does not use the device orientation. --- Example screenshots:  [screenshot-6771.bmp](https://github.com/user-attachments/files/25157071/screenshot-6771.bmp)  [screenshot-14158.bmp](https://github.com/user-attachments/files/25157073/screenshot-14158.bmp) ### AI Usage Did you use AI tools to help write this code? _** YES --------- Co-authored-by: Eliz Kilic <elizk@google.com> Co-authored-by: Xuan Son Nguyen <son@huggingface.co> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Arthur Tazhitdinov <lisnake@gmail.com>
This commit is contained in:
@@ -6,6 +6,38 @@
|
||||
|
||||
#include "BitmapHelpers.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct BmpHeader {
|
||||
struct {
|
||||
uint16_t bfType;
|
||||
uint32_t bfSize;
|
||||
uint16_t bfReserved1;
|
||||
uint16_t bfReserved2;
|
||||
uint32_t bfOffBits;
|
||||
} fileHeader;
|
||||
struct {
|
||||
uint32_t biSize;
|
||||
int32_t biWidth;
|
||||
int32_t biHeight;
|
||||
uint16_t biPlanes;
|
||||
uint16_t biBitCount;
|
||||
uint32_t biCompression;
|
||||
uint32_t biSizeImage;
|
||||
int32_t biXPelsPerMeter;
|
||||
int32_t biYPelsPerMeter;
|
||||
uint32_t biClrUsed;
|
||||
uint32_t biClrImportant;
|
||||
} infoHeader;
|
||||
struct RgbQuad {
|
||||
uint8_t rgbBlue;
|
||||
uint8_t rgbGreen;
|
||||
uint8_t rgbRed;
|
||||
uint8_t rgbReserved;
|
||||
};
|
||||
RgbQuad colors[2];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
enum class BmpReaderError : uint8_t {
|
||||
Ok = 0,
|
||||
FileInvalid,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "BitmapHelpers.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring> // Added for memset
|
||||
|
||||
#include "Bitmap.h"
|
||||
|
||||
// Brightness/Contrast adjustments:
|
||||
constexpr bool USE_BRIGHTNESS = false; // true: apply brightness/gamma adjustments
|
||||
@@ -104,3 +107,44 @@ uint8_t quantize1bit(int gray, int x, int y) {
|
||||
const int adjustedThreshold = 128 + ((threshold - 128) / 2); // Range: 64-192
|
||||
return (gray >= adjustedThreshold) ? 1 : 0;
|
||||
}
|
||||
|
||||
void createBmpHeader(BmpHeader* bmpHeader, int width, int height) {
|
||||
if (!bmpHeader) return;
|
||||
|
||||
// Zero out the memory to ensure no garbage data if called on uninitialized stack memory
|
||||
std::memset(bmpHeader, 0, sizeof(BmpHeader));
|
||||
|
||||
uint32_t rowSize = (width + 31) / 32 * 4;
|
||||
uint32_t imageSize = rowSize * height;
|
||||
uint32_t fileSize = sizeof(BmpHeader) + imageSize;
|
||||
|
||||
bmpHeader->fileHeader.bfType = 0x4D42;
|
||||
bmpHeader->fileHeader.bfSize = fileSize;
|
||||
bmpHeader->fileHeader.bfReserved1 = 0;
|
||||
bmpHeader->fileHeader.bfReserved2 = 0;
|
||||
bmpHeader->fileHeader.bfOffBits = sizeof(BmpHeader);
|
||||
|
||||
bmpHeader->infoHeader.biSize = sizeof(bmpHeader->infoHeader);
|
||||
bmpHeader->infoHeader.biWidth = width;
|
||||
bmpHeader->infoHeader.biHeight = height;
|
||||
bmpHeader->infoHeader.biPlanes = 1;
|
||||
bmpHeader->infoHeader.biBitCount = 1;
|
||||
bmpHeader->infoHeader.biCompression = 0;
|
||||
bmpHeader->infoHeader.biSizeImage = imageSize;
|
||||
bmpHeader->infoHeader.biXPelsPerMeter = 0;
|
||||
bmpHeader->infoHeader.biYPelsPerMeter = 0;
|
||||
bmpHeader->infoHeader.biClrUsed = 0;
|
||||
bmpHeader->infoHeader.biClrImportant = 0;
|
||||
|
||||
// Color 0 (black)
|
||||
bmpHeader->colors[0].rgbBlue = 0;
|
||||
bmpHeader->colors[0].rgbGreen = 0;
|
||||
bmpHeader->colors[0].rgbRed = 0;
|
||||
bmpHeader->colors[0].rgbReserved = 0;
|
||||
|
||||
// Color 1 (white)
|
||||
bmpHeader->colors[1].rgbBlue = 255;
|
||||
bmpHeader->colors[1].rgbGreen = 255;
|
||||
bmpHeader->colors[1].rgbRed = 255;
|
||||
bmpHeader->colors[1].rgbReserved = 0;
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
struct BmpHeader;
|
||||
|
||||
// Helper functions
|
||||
uint8_t quantize(int gray, int x, int y);
|
||||
uint8_t quantizeSimple(int gray);
|
||||
uint8_t quantize1bit(int gray, int x, int y);
|
||||
int adjustPixel(int gray);
|
||||
|
||||
// Populates a 1-bit BMP header in the provided memory.
|
||||
void createBmpHeader(BmpHeader* bmpHeader, int width, int height);
|
||||
|
||||
// 1-bit Atkinson dithering - better quality than noise dithering for thumbnails
|
||||
// Error distribution pattern (same as 2-bit but quantizes to 2 levels):
|
||||
// X 1/8 1/8
|
||||
|
||||
@@ -355,6 +355,7 @@ enum class StrId : uint16_t {
|
||||
STR_BOOK_S_STYLE,
|
||||
STR_EMBEDDED_STYLE,
|
||||
STR_OPDS_SERVER_URL,
|
||||
STR_SCREENSHOT_BUTTON,
|
||||
// Sentinel - must be last
|
||||
_COUNT
|
||||
};
|
||||
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Nahrát"
|
||||
STR_BOOK_S_STYLE: "Styl knihy"
|
||||
STR_EMBEDDED_STYLE: "Vložený styl"
|
||||
STR_OPDS_SERVER_URL: "URL serveru OPDS"
|
||||
STR_SCREENSHOT_BUTTON: "Udělat snímek obrazovky"
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Upload"
|
||||
STR_BOOK_S_STYLE: "Book's Style"
|
||||
STR_EMBEDDED_STYLE: "Embedded Style"
|
||||
STR_OPDS_SERVER_URL: "OPDS Server URL"
|
||||
STR_SCREENSHOT_BUTTON: "Take screenshot"
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Envoi"
|
||||
STR_BOOK_S_STYLE: "Style du livre"
|
||||
STR_EMBEDDED_STYLE: "Style intégré"
|
||||
STR_OPDS_SERVER_URL: "URL du serveur OPDS"
|
||||
STR_SCREENSHOT_BUTTON: "Prendre une capture d'écran"
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Hochladen"
|
||||
STR_BOOK_S_STYLE: "Buch-Stil"
|
||||
STR_EMBEDDED_STYLE: "Eingebetteter Stil"
|
||||
STR_OPDS_SERVER_URL: "OPDS-Server-URL"
|
||||
STR_SCREENSHOT_BUTTON: "Screenshot aufnehmen"
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Enviar"
|
||||
STR_BOOK_S_STYLE: "Estilo do livro"
|
||||
STR_EMBEDDED_STYLE: "Estilo embutido"
|
||||
STR_OPDS_SERVER_URL: "URL do servidor OPDS"
|
||||
STR_SCREENSHOT_BUTTON: "Capturar tela"
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Отправить"
|
||||
STR_BOOK_S_STYLE: "Стиль книги"
|
||||
STR_EMBEDDED_STYLE: "Встроенный стиль"
|
||||
STR_OPDS_SERVER_URL: "URL OPDS сервера"
|
||||
STR_SCREENSHOT_BUTTON: "Сделать снимок экрана"
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Subir"
|
||||
STR_BOOK_S_STYLE: "Estilo del libro"
|
||||
STR_EMBEDDED_STYLE: "Estilo integrado"
|
||||
STR_OPDS_SERVER_URL: "URL del servidor OPDS"
|
||||
STR_SCREENSHOT_BUTTON: "Tomar captura de pantalla"
|
||||
@@ -317,3 +317,4 @@ STR_UPLOAD: "Uppladdning"
|
||||
STR_BOOK_S_STYLE: "Bokstil"
|
||||
STR_EMBEDDED_STYLE: "Inbäddad stil"
|
||||
STR_OPDS_SERVER_URL: "OPDS-serveradress"
|
||||
STR_SCREENSHOT_BUTTON: "Ta en skärmdump"
|
||||
Reference in New Issue
Block a user