import os from PIL import Image class ImageHandler: def __init__(self, base_dir: str): """ Initialize the ImageHandler. :param base_dir: Base directory for storing and retrieving images. """ self.base_dir = base_dir def get_image_path(self, filename: str) -> str: """ Construct the full path for a given image file. :param filename: Relative filename of the image. :return: Full path to the image. """ return os.path.join(self.base_dir, filename) def get_resized_image_path(self, filename: str, width: int, height: int) -> str: """ Construct the path for a resized image. :param filename: Original image filename. :param width: Desired width. :param height: Desired height. :return: Path to the resized image. """ return os.path.join(self.base_dir, f"resized_{width}x{height}_{filename}") def resize_and_save(self, original_path: str, resized_path: str, width: int, height: int): """ Resize and save the image if it doesn't already exist. :param original_path: Path to the original image file. :param resized_path: Path to save the resized image. :param width: Desired width. :param height: Desired height. """ if not os.path.exists(resized_path): with Image.open(original_path) as img: img_resized = img.resize((width, height)) img_resized.save(resized_path, format="JPEG") def generate_image_tag(self, src: str, width: int, height: int, css_class: str = "", alt: str = "") -> str: """ Generate an HTML tag and ensure the image exists with the specified dimensions. :param src: Relative path to the original image. :param width: Desired width of the image. :param height: Desired height of the image. :param css_class: Optional CSS class to add to the tag. :param alt: Alternative text for the image. :return: HTML tag. """ original_path = self.get_image_path(src) if not os.path.isfile(original_path): raise FileNotFoundError(f"Image not found: {src}") # Construct resized image path resized_filename = f"resized_{width}x{height}_{os.path.basename(src)}" resized_path = self.get_resized_image_path(src, width, height) # Resize and save the image if necessary self.resize_and_save(original_path, resized_path, width, height) # Return the tag class_attr = f' class="{css_class}"' if css_class else "" alt_attr = f' alt="{alt}"' if alt else "" return f''