Files
cinny/scripts/makeDecorationThumbs.py
T

49 lines
1.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""Build static picker thumbnails for avatar decorations.
The decorations are animated APNGs (~1 MB each). The settings picker shows
static WebP thumbnails instead and only loads the animated file on hover,
focus or selection, so browsing the catalog costs a few MB, not hundreds.
Usage: python3 scripts/makeDecorationThumbs.py <dir-of-slug.png> <out-dir>
Then upload <out-dir>/*.webp to `${DECORATION_CDN}/thumbs/`.
A missing thumbnail is harmless: the picker falls back to the full PNG.
Requires Pillow (pip install pillow).
"""
import sys
from pathlib import Path
from PIL import Image, ImageSequence
SIZE = 144 # 2x the 72px picker cell
def best_frame(im: Image.Image) -> Image.Image:
# Many animations start (or loop through) an empty frame, so pick the frame
# with the most visible pixels rather than frame 0.
best, best_score = None, -1
frames = list(ImageSequence.Iterator(im))
step = max(1, len(frames) // 24)
for frame in frames[::step]:
rgba = frame.convert('RGBA')
score = sum(rgba.getchannel('A').histogram()[33:])
if score > best_score:
best, best_score = rgba, score
return best
def main(src: str, out: str) -> None:
out_dir = Path(out)
out_dir.mkdir(parents=True, exist_ok=True)
for png in sorted(Path(src).glob('*.png')):
with Image.open(png) as im:
thumb = best_frame(im).resize((SIZE, SIZE), Image.LANCZOS)
thumb.save(out_dir / f'{png.stem}.webp', 'WEBP', quality=82, method=6)
if __name__ == '__main__':
if len(sys.argv) != 3:
sys.exit(__doc__)
main(sys.argv[1], sys.argv[2])