43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
import hashlib
|
|
from functools import lru_cache
|
|
from html import escape
|
|
|
|
PALETTE = (
|
|
("#1b1a17", "#e2a100"),
|
|
("#141414", "#c9c2b2"),
|
|
("#1d1b16", "#b98a2e"),
|
|
("#121417", "#8fa3a8"),
|
|
("#191512", "#d9b779"),
|
|
)
|
|
|
|
|
|
@lru_cache(maxsize=4096)
|
|
def render_avatar_svg(seed, size=64):
|
|
size = max(16, min(int(size), 512))
|
|
try:
|
|
digest = hashlib.sha256(seed.encode("utf-8")).digest()
|
|
background, ink = PALETTE[digest[0] % len(PALETTE)]
|
|
cells = []
|
|
unit = size / 5
|
|
for row in range(5):
|
|
for col in range(3):
|
|
if digest[1 + row * 3 + col] % 2 == 0:
|
|
for mirrored in {col, 4 - col}:
|
|
cells.append(
|
|
f'<rect x="{mirrored * unit:.2f}" y="{row * unit:.2f}" width="{unit:.2f}" height="{unit:.2f}" fill="{ink}"/>'
|
|
)
|
|
body = "".join(cells)
|
|
except Exception:
|
|
background, ink = PALETTE[0]
|
|
letter = escape((seed or "?")[:1].upper())
|
|
body = f'<text x="50%" y="58%" text-anchor="middle" font-family="Georgia, serif" font-size="{size // 2}" fill="{ink}">{letter}</text>'
|
|
return (
|
|
f'<svg xmlns="http://www.w3.org/2000/svg" width="{size}" height="{size}" viewBox="0 0 {size} {size}">'
|
|
f'<rect width="{size}" height="{size}" fill="{background}"/>{body}</svg>'
|
|
)
|
|
|
|
|
|
def avatar_url(seed, size=64):
|
|
return f"/avatar/svg/{seed}?size={size}"
|