gallery.py
At d794128Copy the commit ID
Preview
Code · 2.7 KiB#!/usr/bin/env python3
"""Render a labeled silhouette library and four curated glass compositions."""
from pathlib import Path
import argparse
from PIL import Image, ImageDraw, ImageFont
from shapes import SHAPES
from renderer import render
ROOT=Path(__file__).parent
def glass(role='middle',warmth=0.,hue=0.,opacity=.93):
return dict(role=role,warmth=warmth,hue=hue,opacity=opacity)
def piece(name,center,radius,rotation,role):
return dict(shape=name,center=center,radius=radius,rotation=rotation,material=glass(role))
STUDIES={
'soft-forms':[
piece('cloud',(300,350),240,-.3,'outer'),
piece('bubbles',(588,580),305,.24,'middle'),
piece('pebble',(365,864),240,-.45,'front')],
'cutouts':[
piece('seaweed',(305,365),252,-.3,'outer'),
piece('coral',(604,554),325,.3,'middle'),
piece('bean',(350,835),294,-.7,'front')],
'celestial':[
piece('crescent',(322,350),260,-.22,'outer'),
piece('star',(594,559),326,.21,'middle'),
piece('sparkle',(377,845),282,-.19,'front')],
'orchard':[
piece('apple',(337,395),223,-.18,'outer'),
piece('pear',(614,563),316,.20,'middle'),
piece('lemon',(355,826),277,-.48,'front')]
}
def font(size):
# Pillow's bundled font keeps the sheet portable across operating systems.
return ImageFont.load_default(size=size)
def sampler():
cellw,cellh=360,420
sheet=Image.new('RGB',(1440,1860),(241,235,232));draw=ImageDraw.Draw(sheet)
draw.text((48,36),'GLASS / SHAPE LIBRARY',font=font(30),fill=(46,42,55))
draw.text((48,83),'16 silhouettes · one iridescent material · generated from curves',font=font(17),fill=(104,97,110))
for i,(name,label) in enumerate(SHAPES.items()):
tile=render(scale=.34,specs=[piece(name,(486,565),370,0,'middle')])
tile=tile.crop((0,10,tile.width,355))
x=(i%4)*cellw; y=142+(i//4)*cellh
sheet.paste(tile,(x+(cellw-tile.width)//2,y))
draw.text((x+28,y+357),label,font=font(20),fill=(46,42,55))
draw.text((x+28,y+385),name,font=font(14),fill=(112,103,117))
return sheet
def main():
ap=argparse.ArgumentParser(description=__doc__)
ap.add_argument('--output-dir',type=Path,default=ROOT/'renders')
ap.add_argument('--only',choices=['sampler',*STUDIES],help='Render only one asset')
args=ap.parse_args();args.output_dir.mkdir(parents=True,exist_ok=True)
if args.only in (None,'sampler'):
path=args.output_dir/'shape-library.png';sampler().save(path);print(path)
for name,specs in STUDIES.items():
if args.only in (None,name):
path=args.output_dir/f'shape-study-{name}.png'
render(specs=specs).save(path);print(path)
if __name__=='__main__':main()