import numpy as np, os, shutil
from PIL import Image, ImageDraw, ImageFilter
rng=np.random.default_rng(1377)
OUT="kit/images"
def save(im,name,**kw): im.save(os.path.join(OUT,name),**kw)
import json
meta=json.load(open("sources/meta.json"))
order=["A-view-of-South-Chickamauga-Creek-from-t.jpg","Two-Medicine-Lake-Sinopah-Mtn.jpg","Arches-Landscape-35678281025.jpg","Zuma-Canyon-51999366867.jpg","Jackson-Lake-55547820057.jpg","Lichen-on-petrified-wood-1e1dd44e-e82b-4.jpg"]
names=["01-creek-4032x3024.jpg","02-lake-5302x3110.jpg","03-mesa-6000x4000.jpg","04-flower-5765x4023.jpg","05-shore-6000x4000.jpg","06-lichen-4000x2666.jpg"]
for src,dst in zip(order,names):
shutil.copyfile(f"sources/{src}",os.path.join(OUT,dst))
save(Image.open("sources/Jackson-Lake-55547820057.jpg").resize((1600,1067),Image.LANCZOS),"07-shore-1600x1067.jpg",quality=85)
def fractal(w,h,octaves=7,seed=0):
r=np.random.default_rng(seed); acc=np.zeros((h,w))
for o in range(octaves):
s=2**o; gh,gw=max(2,h*s//256+2),max(2,w*s//256+2)
g=Image.fromarray((r.random((gh,gw))*255).astype(np.uint8)).resize((w,h),Image.BICUBIC)
acc+=np.asarray(g,dtype=float)/(s)
acc-=acc.min(); return acc/acc.max()
def colorize(f,stops):
xs=[s[0] for s in stops]; out=np.zeros(f.shape+(3,))
for c in range(3): out[...,c]=np.interp(f,xs,[s[1][c] for s in stops])
return Image.fromarray(out.astype(np.uint8))
terrain=[(0,(20,40,90)),(0.35,(40,90,150)),(0.4,(200,190,140)),(0.5,(60,120,50)),(0.75,(110,100,80)),(0.9,(240,240,245)),(1,(255,255,255))]
save(colorize(fractal(4000,3000,8,1),terrain).filter(ImageFilter.GaussianBlur(0.6)),"08-terrain-4000x3000.jpg",quality=95)
save(colorize(fractal(3840,1080,7,2),terrain),"09-panorama-3840x1080.jpg",quality=88)
sky=[(0,(255,120,60)),(0.5,(200,80,140)),(1,(30,20,80))]
save(colorize(np.tile(np.linspace(0,1,1920)[:,None],(1,1080))*0.8+fractal(1080,1920,5,3)*0.2,sky),"10-tall-1080x1920.jpg",quality=86)
save(Image.fromarray((rng.random((2000,2000,3))*255).astype(np.uint8)),"11-noise-2000x2000.jpg",quality=90)
plasma=[(0,(10,10,40)),(0.3,(80,20,120)),(0.6,(220,90,60)),(1,(250,230,120))]
save(colorize(fractal(2560,1600,6,4),plasma),"12-plasma-2560x1600.jpg",quality=90)
# Mandelbrot set.
w,h=1920,1080; x=np.linspace(-2.4,1.0,w); yy=np.linspace(-0.95,0.95,h); c=x[None,:]+1j*yy[:,None]; z=np.zeros_like(c); n=np.zeros(c.shape)
for i in range(80):
m=np.abs(z)<=2; z[m]=z[m]**2+c[m]; n[m]+=1
save(colorize(np.sqrt(n/80),plasma),"13-mandelbrot-1920x1080.png",optimize=True)
# Voronoi cells.
w,h=1600,1200; pts=rng.random((60,2))*[w,h]; cols=(rng.random((60,3))*200+40).astype(np.uint8)
gy,gx=np.mgrid[0:h,0:w]; d=np.full((h,w),1e18); idx=np.zeros((h,w),int)
for k,(px,py) in enumerate(pts):
dd=(gx-px)**2+(gy-py)**2; m=dd<d; d[m]=dd[m]; idx[m]=k
save(Image.fromarray(cols[idx]),"14-voronoi-1600x1200.png",optimize=True)
# Flat graphics, with and without alpha.
im=Image.new("RGB",(2048,2048),(245,242,235)); dr=ImageDraw.Draw(im)
for i in range(40):
x0,y0=rng.integers(0,1800,2); s=int(rng.integers(80,400)); dr.ellipse((x0,y0,x0+s,y0+s),fill=tuple(int(v) for v in rng.integers(40,220,3)))
save(im,"15-shapes-2048x2048.png",optimize=True)
im=Image.new("RGBA",(1200,800),(0,0,0,0)); dr=ImageDraw.Draw(im)
for i in range(12):
x0,y0=rng.integers(0,1000,1)[0],rng.integers(0,600,1)[0]; dr.rounded_rectangle((x0,y0,x0+220,y0+160),radius=30,fill=tuple(int(v) for v in rng.integers(30,230,3))+(200,))
save(im,"16-alpha-1200x800.png",optimize=True)
for size,name in [(512,"17-badge-512.png"),(64,"18-badge-64.png")]:
im=Image.new("RGBA",(size,size),(0,0,0,0)); dr=ImageDraw.Draw(im); dr.ellipse((0,0,size-1,size-1),fill=(70,110,200,255)); dr.regular_polygon((size/2,size/2,size*0.3),6,fill=(250,250,250,255))
save(im,name,optimize=True)
im=Image.new("RGB",(1600,900),(255,255,255)); dr=ImageDraw.Draw(im)
for i in range(0,1600,80): dr.line((i,0,i,900),fill=(225,225,230),width=1)
for j in range(0,900,80): dr.line((0,j,1600,j),fill=(225,225,230),width=1)
pts=[(i*40,450+int(250*np.sin(i/5)+rng.normal(0,20))) for i in range(41)]; dr.line(pts,fill=(30,90,200),width=4)
save(im,"19-chart-1600x900.png",optimize=True)
save(colorize(fractal(1280,960,6,5),terrain),"20-terrain-1280x960.webp",quality=82)