From c5414a8e215594eea6e616f8236d00e831d20bbf Mon Sep 17 00:00:00 2001 From: Daniel Schwarz Date: Fri, 7 Jun 2024 22:00:57 -0400 Subject: [PATCH] Added support for indexed color image rendering; fixes #483 Useful for terminals that do not support truecolor, such as MacOS Terminal. Requires term-image 0.7.2 or later. --- pyproject.toml | 2 +- toot/tui/images.py | 8 +++++--- toot/tui/overlays.py | 6 ++++-- toot/tui/timeline.py | 6 ++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 963f6bfb..80d50729 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ # Required to display images in the TUI images = [ "pillow>=9.5.0", - "term-image==0.7.0", + "term-image>=0.7.2", ] # Required to display rich text in the TUI diff --git a/toot/tui/images.py b/toot/tui/images.py index c74489c2..9dfebec4 100644 --- a/toot/tui/images.py +++ b/toot/tui/images.py @@ -22,7 +22,7 @@ def image_support_enabled(): def can_render_pixels(image_format): return image_format in _IMAGE_PIXEL_FORMATS - def get_base_image(image, image_format) -> BaseImage: + def get_base_image(image, image_format, colors) -> BaseImage: # we don't autodetect kitty, iterm; we choose based on option switches global _ImageCls @@ -36,6 +36,8 @@ def get_base_image(image, image_format) -> BaseImage: else BlockImage ) _ImageCls.forced_support = True + if colors == 256 and not can_render_pixels(image_format): + _ImageCls.set_render_method("INDEXED") return _ImageCls(image) @@ -79,7 +81,7 @@ def load_image(url): except Exception: return None - def graphics_widget(img, image_format="block", corner_radius=0) -> urwid.Widget: + def graphics_widget(img, image_format="block", corner_radius=0, colors=16777216) -> urwid.Widget: if not img: return urwid.SolidFill(fill_char=" ") @@ -88,7 +90,7 @@ def graphics_widget(img, image_format="block", corner_radius=0) -> urwid.Widget: else: render_img = img - return UrwidImage(get_base_image(render_img, image_format), '<', upscale=True) + return UrwidImage(get_base_image(render_img, image_format, colors), '<', upscale=True) # "<" means left-justify the image except ImportError: diff --git a/toot/tui/overlays.py b/toot/tui/overlays.py index c0f5d8da..b357bd4d 100644 --- a/toot/tui/overlays.py +++ b/toot/tui/overlays.py @@ -262,7 +262,8 @@ def account_header(self, account): if image_support_enabled() and account['avatar'] and not account["avatar"].endswith("missing.png"): img = load_image(account['avatar']) aimg = urwid.BoxAdapter( - graphics_widget(img, image_format=self.options.image_format, corner_radius=10), 10) + graphics_widget(img, image_format=self.options.image_format, corner_radius=10, + colors=self.options.colors), 10) else: aimg = urwid.BoxAdapter(urwid.SolidFill(" "), 10) @@ -270,7 +271,8 @@ def account_header(self, account): img = load_image(account['header']) himg = (urwid.BoxAdapter( - graphics_widget(img, image_format=self.options.image_format, corner_radius=10), 10)) + graphics_widget(img, image_format=self.options.image_format, corner_radius=10, + colors=self.options.colors), 10)) else: himg = urwid.BoxAdapter(urwid.SolidFill(" "), 10) diff --git a/toot/tui/timeline.py b/toot/tui/timeline.py index 88351786..018ca40c 100644 --- a/toot/tui/timeline.py +++ b/toot/tui/timeline.py @@ -339,7 +339,8 @@ def update_status_image(self, status, path, placeholder_index): if img: try: status.placeholders[placeholder_index]._set_original_widget( - graphics_widget(img, image_format=self.tui.options.image_format, corner_radius=10)) + graphics_widget(img, image_format=self.tui.options.image_format, corner_radius=10, + colors=self.tui.options.colors)) except IndexError: # ignore IndexErrors. @@ -408,7 +409,8 @@ def image_widget(self, path, rows=None, aspect=None) -> urwid.Widget: pass if img: return (urwid.BoxAdapter( - graphics_widget(img, image_format=self.timeline.tui.options.image_format, corner_radius=10), rows)) + graphics_widget(img, image_format=self.timeline.tui.options.image_format, corner_radius=10, + colors=self.timeline.tui.options.colors), rows)) else: placeholder = urwid.BoxAdapter(urwid.SolidFill(fill_char=" "), rows) self.status.placeholders.append(placeholder)