Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion textual_image/_pixeldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ class PixelData:
"""Provides access to pixel data from a path or `PIL.Image.Image` instance."""

def __init__(
self, image: StrOrBytesPath | IO[bytes] | PILImage.Image, mode: Literal["grayscale", "rgb"] | None = None
self,
image: StrOrBytesPath | IO[bytes] | PILImage.Image,
mode: Literal["grayscale", "rgb", "rgba"] | None = None,
) -> None:
"""Initializes a PixelData.

Expand All @@ -68,6 +70,8 @@ def __init__(
self._image = self._image.convert("L")
elif mode == "rgb":
self._image = self._image.convert("RGB")
elif mode == "rgba":
self._image = self._image.convert("RGBA")

@property
def pil_image(self) -> PILImage.Image:
Expand Down
17 changes: 13 additions & 4 deletions textual_image/renderable/halfcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from textual_image._utils import StrOrBytesPath, grouped


def _map_pixel(pixel_value: Tuple[int, int, int]) -> Color:
def _map_pixel(pixel_value: Tuple[int, int, int, int]) -> Color:
"""Maps a pixel value to a colored halfcells.

Args:
Expand All @@ -25,7 +25,7 @@ def _map_pixel(pixel_value: Tuple[int, int, int]) -> Color:
Returns:
Color resembling the pixel value.
"""
return Color.from_triplet(ColorTriplet(*pixel_value))
return Color.from_triplet(ColorTriplet(*(pixel_value[:3])))


class Image:
Expand All @@ -47,7 +47,7 @@ def __init__(
height: height specification to render the image.
See `textual_image.geometry.ImageSize` for details about possible values.
"""
self._image_data = PixelData(image, mode="rgb")
self._image_data = PixelData(image, mode="rgba")
self._render_size = ImageSize(self._image_data.width, self._image_data.height, width, height)

def cleanup(self) -> None:
Expand All @@ -73,7 +73,16 @@ def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderR

for upper_row, lower_row in grouped(self._image_data.scaled(width, height), 2):
for upper_pixel, lower_pixel in zip(upper_row, lower_row, strict=True):
yield Segment("▀", style=Style(color=_map_pixel(upper_pixel), bgcolor=_map_pixel(lower_pixel))) # type: ignore
if upper_pixel[3] == lower_pixel[3] == 0:
yield Segment(" ")
elif upper_pixel[3] == 0:
yield Segment("▄", style=Style(color=_map_pixel(lower_pixel[:3])))
elif lower_pixel[3] == 0:
yield Segment("▀", style=Style(color=_map_pixel(upper_pixel[:3])))
else:
yield Segment(
"▀", style=Style(color=_map_pixel(upper_pixel[:3]), bgcolor=_map_pixel(lower_pixel[:3]))
)
yield Segment("\n")

def __rich_measure__(self, console: Console, options: ConsoleOptions) -> Measurement:
Expand Down
Loading