| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- #!/usr/bin/env python3
- """Generate placeholder sticker PNGs for the default packs."""
- import math
- import os
- import struct
- import zlib
- ROOT = os.path.join(os.path.dirname(__file__), "..", "data", "stickers")
- SIZE = 96
- def chunk(tag, data):
- crc = zlib.crc32(tag + data) & 0xFFFFFFFF
- return struct.pack(">I", len(data)) + tag + data + struct.pack(">I", crc)
- def encode_png(pixels):
- raw = b""
- for y in range(SIZE):
- raw += b"\x00"
- for x in range(SIZE):
- raw += bytes(pixels[y][x])
- return (
- b"\x89PNG\r\n\x1a\n"
- + chunk(b"IHDR", struct.pack(">IIBBBBB", SIZE, SIZE, 8, 6, 0, 0, 0))
- + chunk(b"IDAT", zlib.compress(raw, 9))
- + chunk(b"IEND", b"")
- )
- def blank(fill=(0, 0, 0, 0)):
- return [[fill for _ in range(SIZE)] for _ in range(SIZE)]
- def setp(px, x, y, c):
- if 0 <= x < SIZE and 0 <= y < SIZE:
- px[y][x] = c
- def disk(px, cx, cy, r, color):
- r2 = r * r
- for y in range(int(cy - r), int(cy + r) + 1):
- for x in range(int(cx - r), int(cx + r) + 1):
- if (x - cx) ** 2 + (y - cy) ** 2 <= r2:
- setp(px, x, y, color)
- def ring(px, cx, cy, r, w, color):
- r2 = r * r
- inner = (r - w) ** 2
- for y in range(int(cy - r), int(cy + r) + 1):
- for x in range(int(cx - r), int(cx + r) + 1):
- d = (x - cx) ** 2 + (y - cy) ** 2
- if inner <= d <= r2:
- setp(px, x, y, color)
- def line(px, x0, y0, x1, y1, w, color):
- steps = max(abs(x1 - x0), abs(y1 - y0), 1)
- for i in range(steps + 1):
- t = i / steps
- x = x0 + (x1 - x0) * t
- y = y0 + (y1 - y0) * t
- disk(px, x, y, w, color)
- def save(pack, code, px):
- d = os.path.join(ROOT, str(pack))
- os.makedirs(d, exist_ok=True)
- path = os.path.join(d, code + ".png")
- with open(path, "wb") as f:
- f.write(encode_png(px))
- print("wrote", path)
- def face_base(color=(255, 214, 64, 255)):
- px = blank()
- disk(px, 48, 48, 40, color)
- return px
- def smile():
- px = face_base()
- disk(px, 34, 40, 5, (60, 40, 20, 255))
- disk(px, 62, 40, 5, (60, 40, 20, 255))
- line(px, 32, 62, 48, 70, 3, (60, 40, 20, 255))
- line(px, 48, 70, 64, 62, 3, (60, 40, 20, 255))
- save(1, "smile", px)
- def laugh():
- px = face_base()
- disk(px, 34, 38, 5, (60, 40, 20, 255))
- disk(px, 62, 38, 5, (60, 40, 20, 255))
- disk(px, 48, 64, 14, (60, 40, 20, 255))
- disk(px, 48, 60, 12, (255, 214, 64, 255))
- save(1, "laugh", px)
- def sad():
- px = face_base((130, 180, 255, 255))
- disk(px, 34, 42, 5, (40, 50, 90, 255))
- disk(px, 62, 42, 5, (40, 50, 90, 255))
- line(px, 32, 70, 48, 62, 3, (40, 50, 90, 255))
- line(px, 48, 62, 64, 70, 3, (40, 50, 90, 255))
- disk(px, 70, 58, 5, (80, 140, 255, 255))
- save(1, "sad", px)
- def angry():
- px = face_base((255, 120, 90, 255))
- disk(px, 34, 44, 5, (80, 20, 20, 255))
- disk(px, 62, 44, 5, (80, 20, 20, 255))
- line(px, 24, 32, 42, 40, 3, (80, 20, 20, 255))
- line(px, 72, 32, 54, 40, 3, (80, 20, 20, 255))
- line(px, 34, 68, 62, 68, 3, (80, 20, 20, 255))
- save(1, "angry", px)
- def cool():
- px = face_base()
- disk(px, 34, 42, 10, (30, 30, 30, 255))
- disk(px, 62, 42, 10, (30, 30, 30, 255))
- line(px, 44, 42, 52, 42, 3, (30, 30, 30, 255))
- line(px, 32, 66, 64, 66, 3, (60, 40, 20, 255))
- save(1, "cool", px)
- def wow():
- px = face_base((255, 230, 120, 255))
- ring(px, 34, 40, 8, 3, (60, 40, 20, 255))
- ring(px, 62, 40, 8, 3, (60, 40, 20, 255))
- disk(px, 48, 66, 9, (60, 40, 20, 255))
- save(1, "wow", px)
- def sleep():
- px = face_base((200, 210, 255, 255))
- line(px, 26, 42, 42, 42, 3, (60, 40, 80, 255))
- line(px, 54, 42, 70, 42, 3, (60, 40, 80, 255))
- line(px, 34, 66, 62, 66, 3, (60, 40, 80, 255))
- disk(px, 74, 24, 6, (140, 120, 255, 255))
- save(1, "sleep", px)
- def shy():
- px = face_base((255, 200, 210, 255))
- disk(px, 34, 42, 4, (80, 40, 50, 255))
- disk(px, 62, 42, 4, (80, 40, 50, 255))
- disk(px, 26, 56, 7, (255, 140, 150, 180))
- disk(px, 70, 56, 7, (255, 140, 150, 180))
- line(px, 38, 66, 58, 66, 2, (80, 40, 50, 255))
- save(1, "shy", px)
- def like():
- px = blank()
- disk(px, 48, 52, 28, (7, 193, 96, 255))
- line(px, 40, 58, 40, 30, 6, (255, 255, 255, 255))
- disk(px, 54, 36, 10, (255, 255, 255, 255))
- save(2, "like", px)
- def ok():
- px = blank()
- disk(px, 48, 48, 30, (64, 158, 255, 255))
- ring(px, 48, 48, 14, 5, (255, 255, 255, 255))
- save(2, "ok", px)
- def clap():
- px = blank()
- disk(px, 36, 52, 18, (255, 180, 70, 255))
- disk(px, 60, 44, 18, (255, 200, 90, 255))
- save(2, "clap", px)
- def wave():
- px = blank()
- disk(px, 48, 58, 22, (255, 210, 140, 255))
- disk(px, 62, 30, 12, (255, 210, 140, 255))
- save(2, "wave", px)
- if __name__ == "__main__":
- smile()
- laugh()
- sad()
- angry()
- cool()
- wow()
- sleep()
- shy()
- like()
- ok()
- clap()
- wave()
|