feat: Draw transparent image for icons (#18)

Adding a method to the display renderer to support drawing images
without coloring the white pixels, essentially drawing transparent
images for icons in the Lyra Icons PR
https://github.com/crosspoint-reader/crosspoint-reader/pull/725
This commit is contained in:
CaptainFrito
2026-02-10 19:33:42 +11:00
committed by GitHub
parent c8ce3949b3
commit 91e7e2bef7
2 changed files with 33 additions and 1 deletions
@@ -29,7 +29,7 @@ class EInkDisplay {
// Frame buffer operations
void clearScreen(uint8_t color = 0xFF) const;
void drawImage(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false) const;
void drawImageTransparent(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false) const;
#ifndef EINK_DISPLAY_SINGLE_BUFFER_MODE
void swapBuffers();
#endif
@@ -343,6 +343,38 @@ void EInkDisplay::drawImage(const uint8_t* imageData, const uint16_t x, const ui
if (Serial) Serial.printf("[%lu] Image drawn to frame buffer\n", millis());
}
// Draws only black pixels from the image, leaves white pixels clear (unchanged in framebuffer)
void EInkDisplay::drawImageTransparent(const uint8_t* imageData, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h,
const bool fromProgmem) const {
if (!frameBuffer) {
Serial.printf("[%lu] ERROR: Frame buffer not allocated!\n", millis());
return;
}
// Calculate bytes per line for the image
const uint16_t imageWidthBytes = w / 8;
// Copy only black pixels to frame buffer
for (uint16_t row = 0; row < h; row++) {
const uint16_t destY = y + row;
if (destY >= DISPLAY_HEIGHT)
break;
const uint16_t destOffset = destY * DISPLAY_WIDTH_BYTES + (x / 8);
const uint16_t srcOffset = row * imageWidthBytes;
for (uint16_t col = 0; col < imageWidthBytes; col++) {
if ((x / 8 + col) >= DISPLAY_WIDTH_BYTES)
break;
uint8_t srcByte = fromProgmem ? pgm_read_byte(&imageData[srcOffset + col]) : imageData[srcOffset + col];
frameBuffer[destOffset + col] &= srcByte;
}
}
Serial.printf("[%lu] Transparent image drawn to frame buffer\n", millis());
}
void EInkDisplay::writeRamBuffer(uint8_t ramBuffer, const uint8_t* data, uint32_t size) {
const char* bufferName = (ramBuffer == CMD_WRITE_RAM_BW) ? "BW" : "RED";
const unsigned long startTime = millis();