From b9af01f8ae486701070591efcfc28c8c549dc229 Mon Sep 17 00:00:00 2001 From: Thomas Rosenau Date: Sun, 2 Feb 2025 19:09:30 +0100 Subject: [PATCH] Add grayscale image conversion (#71) --- epdlib/Screen.py | 25 +++++++++++++++++++++++-- epdlib/constants.py | 20 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/epdlib/Screen.py b/epdlib/Screen.py index 3565b8e..da07556 100755 --- a/epdlib/Screen.py +++ b/epdlib/Screen.py @@ -672,12 +672,12 @@ def _full_writeEPD_non_hd(self, image): try: if self.screen_type == ScreenType.FOUR_GRAYS: - logging.debug('one-bit display') + logging.debug('4 grayscale display') self.epd.display_4Gray(image_buffer) elif self.screen_type == ScreenType.THREE_COLORS: # displays that require multiple images logging.debug('bi-color display') self.epd.display(image_buffer, self.buffer_no_image) - else: # 7 color displays + else: # 7 color or monochrome displays logging.debug('seven-color or monochrome display') self.epd.display(image_buffer) @@ -771,6 +771,27 @@ def module_exit(self): logging.warning(f'failed to sleep module: {e}') raise ScreenError(e) + @staticmethod + def image_to_4_grays(image): + logging.debug('converting image to 4 grays') + + ''' + Waveshare displays do not render colors accurately. + For example, an input color of "#808080" looks more like "#a9aca3" on the ePaper. + Therefore, we convert our images to grayscale in 2 steps: + 1. Convert colors to their actual displayed output + 2. Update palette to reverse the error + ''' + palette = Screen.colors2palette(constants.COLORS_4GRAY_NATURAL.values()) + palette_img = Image.new('P', (1, 1)) + palette_img.putpalette(palette) + image_gs = image.convert('RGB').quantize(palette=palette_img) + + ws_palette = Screen.colors2palette(constants.COLORS_4GRAY_WS.values()) + image_gs.putpalette(ws_palette) + return image_gs + + # + code_folding=[] def list_compatible_modules(print_modules=True, reasons=False): diff --git a/epdlib/constants.py b/epdlib/constants.py index 971e743..1b7f1da 100644 --- a/epdlib/constants.py +++ b/epdlib/constants.py @@ -23,6 +23,26 @@ 'ORANGE': (255, 128, 0) } +COLORS_4GRAY_WS = { + 'BLACK': (0, 0, 0), + 'DARK_GRAY': (0x80, 0x80, 0x80), + 'BRIGHT_GRAY': (0xc0, 0xc0, 0xc0), + 'WHITE': (0xff, 0xff, 0xff) +} + +''' +"natural" display colors of 4 grayscale displays. +Tweaking these may improve image rendering. +The present values are based on experiments with a 2.7" e-Paper HAT, +using various photographs and graphics as test inputs. +''' +COLORS_4GRAY_NATURAL = { + 'BLACK': (0x1b, 0x1b, 0x13), + 'DARK_GRAY': (0x4d, 0x4d, 0x44), + 'BRIGHT_GRAY': (0xa9, 0xac, 0xa3), + 'WHITE': (0xeb, 0xea, 0xdf) +} + CLEAR_COLOR = 0xFF LAYOUT_DEFAULTS = {