agent_m/agentm/components/game_image_preview.py

49 lines
1.6 KiB
Python

from textual.widgets import Static
from PIL import Image, ImageFilter
from rich_pixels import Pixels
from rich_pixels._renderer import HalfcellRenderer
from pathlib import Path
class GameImagePreview(Static):
def __init__(
self,
image_path: str,
*,
scale_factor: float = 0.098,
fallback_text: str = "[red]Failed to load image[/red]",
**kwargs
):
self.image_path = image_path
self.scale_factor = scale_factor
self.fallback_text = fallback_text
renderable = self.load_and_process_image()
# THIS is the key line that makes the image render:
super().__init__(renderable, **kwargs)
def load_and_process_image(self):
path = Path(self.image_path)
if not path.exists() or not path.is_file():
return f"{self.fallback_text}\n[dim]Not found: {self.image_path}[/]"
try:
with Image.open(path) as img:
if img.mode != "RGBA":
img = img.convert("RGBA")
resized = img.resize(
(
int(img.width * self.scale_factor),
int(img.height * self.scale_factor),
),
resample=Image.Resampling.LANCZOS,
)
resized = resized.filter(ImageFilter.UnsharpMask(radius=1, percent=150, threshold=3))
return Pixels.from_image(
resized,
renderer=HalfcellRenderer(default_color="black"),
)
except Exception as e:
return f"{self.fallback_text}\n[dim]{e}[/]"