"""Pre-scale the carousel imagery so browsers never upscale it. The refined fabric shots top out at 1024-1376px, but the full-bleed hero paints them across up to ~1920 CSS px (3840 device px on retina). Browsers enlarge them at render time and the knit stitches smear. Resampling once with Lanczos plus a light unsharp pass keeps the texture readable and, at these sizes, costs about the same bytes as the originals. Requires Pillow. Generated assets are committed; runtime needs nothing. """ from pathlib import Path import sys from PIL import Image, ImageFilter ROOT = Path(__file__).resolve().parents[1] TARGETS = [ROOT / "public" / "images" / "refined" / "hero", ROOT / "public" / "images" / "refined" / "products"] LONG_EDGE = 2048 QUALITY = 82 def optimize(path): with Image.open(path) as source: image = source.convert("RGB") scale = LONG_EDGE / max(image.size) if scale > 1: image = image.resize( (round(image.width * scale), round(image.height * scale)), Image.Resampling.LANCZOS, ) image = image.filter(ImageFilter.UnsharpMask(radius=1.0, percent=60, threshold=3)) before = path.stat().st_size image.save(path, quality=QUALITY, optimize=True, progressive=True) after = path.stat().st_size print(f"{path.relative_to(ROOT)} {image.size} {before // 1024}KB -> {after // 1024}KB") if __name__ == "__main__": files = sorted(p for target in TARGETS for p in target.rglob("*.jpeg")) if not files: sys.exit("no carousel images found") for file in files: optimize(file)