from PIL import Image import os def add_transparent_border(img: Image.Image) -> Image.Image: border_size = 50 new_size = (img.width + 2 * border_size, img.height + 2 * border_size) new_img = Image.new('RGBA', new_size) new_img.paste(img, (border_size, border_size)) return new_img def add_background(img: Image.Image) -> Image.Image: bg_color = (28, 28, 28) if img.mode != 'RGBA': img = img.convert('RGBA') background = Image.new('RGBA', img.size, bg_color + (255,)) combined = Image.alpha_composite(background, img) return combined.convert('RGB') def resize_image(img: Image.Image, max_width: int) -> Image.Image: if img.width > max_width: scale_ratio = max_width / img.width new_height = int(img.height * scale_ratio) img = img.resize((max_width, new_height), Image.LANCZOS) return img def convert_to_webp(img: Image.Image, output_path: str) -> None: img.save(output_path, 'WEBP') def print_image_stats(name: str, before_size: int, after_size: int, before_dims: tuple, after_dims: tuple) -> None: before_size_mb = before_size / (1024 * 1024) after_size_mb = after_size / (1024 * 1024) pixel_reduction = int((after_dims[0] * after_dims[1]) / (before_dims[0] * before_dims[1]) * 100) print(f'\n{name}') print(f'Before: {before_dims[0]}x{before_dims[1]}, {before_size_mb:.2f} MB') print(f'After: {after_dims[0]}x{after_dims[1]}, {after_size_mb:.2f} MB') print(f'Size reduction: {100 - pixel_reduction}%') def process_image(img_path: str, directory: str, max_width: int) -> None: before_size = os.path.getsize(img_path) with Image.open(img_path) as img: before_dims = img.size img = add_transparent_border(img) img = add_background(img) img = resize_image(img, max_width) after_dims = img.size output_path = img_path.rsplit('.', 1)[0] + '.webp' convert_to_webp(img, output_path) after_size = os.path.getsize(output_path) print_image_stats(img_path, before_size, after_size, before_dims, after_dims) os.remove(img_path) def resize_and_convert_directory(directory: str, max_width: int) -> None: total_before_size = 0 total_after_size = 0 num_images = 0 for filename in os.listdir(directory): if filename.lower().endswith(('.png', '.jpg', '.jpeg')): num_images += 1 img_path = os.path.join(directory, filename) before_size = os.path.getsize(img_path) total_before_size += before_size process_image(img_path, directory, max_width) new_filename = filename.rsplit('.', 1)[0] + '.webp' new_path = os.path.join(directory, new_filename) after_size = os.path.getsize(new_path) total_after_size += after_size if num_images > 0: avg_reduction = int((total_after_size / total_before_size) * 100) total_before_mb = total_before_size / (1024 * 1024) total_after_mb = total_after_size / (1024 * 1024) print(f'\n--------------\nTotal Before: {total_before_mb:.2f} MB, Total After: {total_after_mb:.2f} MB') print(f'Average Size Reduction: {100 - avg_reduction}%') print(f'Total Images Processed: {num_images}') def adapt_bg_directory(directory: str) -> None: for filename in os.listdir(directory): if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')): img_path = os.path.join(directory, filename) with Image.open(img_path) as img: img = add_transparent_border(img) img = add_background(img) img.save(img_path) if __name__ == '__main__': resize_and_convert_directory('public/images/articles/welcome-to-majordom', 1010)