feat: Add support to B&W filters to image covers (#476)
* **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Implementation of a new feature in Display options as Image Filter * **What changes are included?** Black & White and Inverted Black & White options are added. Here are some examples: | None | Contrast | Inverted | | --- | --- | --- | | <img alt="image" src="https://github.com/user-attachments/assets/fe02dd9b-f647-41bd-8495-c262f73177c4" /> | <img alt="image" src="https://github.com/user-attachments/assets/2d17747d-3ff6-48a9-b9b9-eb17cccf19cf" /> | <img alt="image" src="https://github.com/user-attachments/assets/792dea50-f003-4634-83fe-77849ca49095" /> | | <img alt="image" src="https://github.com/user-attachments/assets/28395b63-14f8-41e2-886b-8ddf3faeafc4" /> | <img alt="image" src="https://github.com/user-attachments/assets/71a569c8-fc54-4647-ad4c-ec96e220cddb" /> | <img alt="image" src="https://github.com/user-attachments/assets/9139e32c-9175-433e-8372-45fa042d3dc9" /> | * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). I have also tried adding Color inversion, but could not see much difference with that. It might be because my implementation was wrong. --- While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _** PARTIALLY **_ --------- Co-authored-by: Dave Allie <dave@daveallie.com>
This commit is contained in:
@@ -23,7 +23,7 @@ void readAndValidate(FsFile& file, uint8_t& member, const uint8_t maxValue) {
|
||||
namespace {
|
||||
constexpr uint8_t SETTINGS_FILE_VERSION = 1;
|
||||
// Increment this when adding new persisted settings fields
|
||||
constexpr uint8_t SETTINGS_COUNT = 25; // User's 23 + OPDS auth (2)
|
||||
constexpr uint8_t SETTINGS_COUNT = 26; // 25 + sleepScreenCoverFilter
|
||||
constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin";
|
||||
} // namespace
|
||||
|
||||
@@ -64,6 +64,9 @@ bool CrossPointSettings::saveToFile() const {
|
||||
// OPDS auth fields added for PR #404
|
||||
serialization::writeString(outputFile, std::string(opdsUsername));
|
||||
serialization::writeString(outputFile, std::string(opdsPassword));
|
||||
// PR #476: B&W filter for cover images
|
||||
serialization::writePod(outputFile, sleepScreenCoverFilter);
|
||||
// New fields added at end for backward compatibility
|
||||
outputFile.close();
|
||||
|
||||
Serial.printf("[%lu] [CPS] Settings saved to file\n", millis());
|
||||
@@ -161,6 +164,10 @@ bool CrossPointSettings::loadFromFile() {
|
||||
opdsPassword[sizeof(opdsPassword) - 1] = '\0';
|
||||
}
|
||||
if (++settingsRead >= fileSettingsCount) break;
|
||||
// PR #476: B&W filter for cover images
|
||||
readAndValidate(inputFile, sleepScreenCoverFilter, SLEEP_SCREEN_COVER_FILTER_COUNT);
|
||||
if (++settingsRead >= fileSettingsCount) break;
|
||||
// New fields added at end for backward compatibility
|
||||
} while (false);
|
||||
|
||||
inputFile.close();
|
||||
|
||||
@@ -18,6 +18,12 @@ class CrossPointSettings {
|
||||
// Should match with SettingsActivity text
|
||||
enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3, BLANK = 4, SLEEP_SCREEN_MODE_COUNT };
|
||||
enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, ACTUAL = 2, SLEEP_SCREEN_COVER_MODE_COUNT };
|
||||
enum SLEEP_SCREEN_COVER_FILTER {
|
||||
NO_FILTER = 0,
|
||||
BLACK_AND_WHITE = 1,
|
||||
INVERTED_BLACK_AND_WHITE = 2,
|
||||
SLEEP_SCREEN_COVER_FILTER_COUNT
|
||||
};
|
||||
|
||||
// Status bar display type enum
|
||||
enum STATUS_BAR_MODE { NONE = 0, NO_PROGRESS = 1, FULL = 2, FULL_WITH_PROGRESS_BAR = 3, ONLY_PROGRESS_BAR = 4, STATUS_BAR_MODE_COUNT };
|
||||
@@ -89,6 +95,8 @@ class CrossPointSettings {
|
||||
uint8_t sleepScreen = DARK;
|
||||
// Sleep screen cover mode settings
|
||||
uint8_t sleepScreenCoverMode = FIT;
|
||||
// Sleep screen cover filter
|
||||
uint8_t sleepScreenCoverFilter = NO_FILTER;
|
||||
// Status bar settings
|
||||
uint8_t statusBar = FULL;
|
||||
// Text rendering settings
|
||||
|
||||
@@ -233,6 +233,10 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap, const std::str
|
||||
millis(), edges.top, edges.bottom, edges.left, edges.right,
|
||||
topGray, bottomGray, leftGray, rightGray);
|
||||
|
||||
// Check if greyscale pass should be used (PR #476: skip if filter is applied)
|
||||
const bool hasGreyscale = bitmap.hasGreyscale() &&
|
||||
SETTINGS.sleepScreenCoverFilter == CrossPointSettings::SLEEP_SCREEN_COVER_FILTER::NO_FILTER;
|
||||
|
||||
// Clear screen to white first (default background)
|
||||
renderer.clearScreen(0xFF);
|
||||
|
||||
@@ -256,9 +260,15 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap, const std::str
|
||||
|
||||
Serial.printf("[%lu] [SLP] drawing bitmap at %d, %d\n", millis(), x, y);
|
||||
renderer.drawBitmap(bitmap, x, y, drawWidth, drawHeight, cropX, cropY);
|
||||
|
||||
// PR #476: Apply inverted B&W filter if selected
|
||||
if (SETTINGS.sleepScreenCoverFilter == CrossPointSettings::SLEEP_SCREEN_COVER_FILTER::INVERTED_BLACK_AND_WHITE) {
|
||||
renderer.invertScreen();
|
||||
}
|
||||
|
||||
renderer.displayBuffer(EInkDisplay::HALF_REFRESH);
|
||||
|
||||
if (bitmap.hasGreyscale()) {
|
||||
if (hasGreyscale) {
|
||||
// Grayscale LSB pass
|
||||
bitmap.rewindToData();
|
||||
renderer.clearScreen(0x00);
|
||||
|
||||
@@ -12,11 +12,13 @@
|
||||
const char* SettingsActivity::categoryNames[categoryCount] = {"Display", "Reader", "Controls", "System"};
|
||||
|
||||
namespace {
|
||||
constexpr int displaySettingsCount = 5;
|
||||
constexpr int displaySettingsCount = 7;
|
||||
const SettingInfo displaySettings[displaySettingsCount] = {
|
||||
// Should match with SLEEP_SCREEN_MODE
|
||||
SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}),
|
||||
SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop", "Actual"}),
|
||||
SettingInfo::Enum("Sleep Screen Cover Filter", &CrossPointSettings::sleepScreenCoverFilter,
|
||||
{"None", "Contrast", "Inverted"}),
|
||||
SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar,
|
||||
{"None", "No Progress", "Full w/ Percentage", "Full w/ Progress Bar", "Progress Bar"}),
|
||||
SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}),
|
||||
|
||||
Reference in New Issue
Block a user