Skip to content

Instantly share code, notes, and snippets.

@EnigmaCurry
Last active September 8, 2018 01:39
Show Gist options
  • Save EnigmaCurry/12cb7fa20664c43074afed27ba53e751 to your computer and use it in GitHub Desktop.
Save EnigmaCurry/12cb7fa20664c43074afed27ba53e751 to your computer and use it in GitHub Desktop.
Serverless Psychedelic Art
#!/bin/sh
gcloud beta functions deploy psychedelic_art --runtime python37 --trigger-http
# Random Psychedelic Art - https://jeremykun.com/2012/01/01/random-psychedelic-art/
# Deterministic Refactor by EnigmaCurry
from PIL import Image
import random, math
from flask import send_file
from io import BytesIO
def make_image(seed=None, size=150, debug=False):
rng = random.Random(seed)
def buildExpr(prob = 0.99):
if rng.random() < prob:
return rng.choice([SinPi, CosPi, Times])(prob)
else:
return rng.choice([X, Y])()
class X:
def eval(self, x, y):
return x
def __str__(self):
return "x"
class Y:
def eval(self, x, y):
return y
def __str__(self):
return "y"
class SinPi:
def __init__(self, prob):
self.arg = buildExpr(prob * prob)
def __str__(self):
return "sin(pi*" + str(self.arg) + ")"
def eval(self, x, y):
return math.sin(math.pi * self.arg.eval(x,y))
class CosPi:
def __init__(self, prob):
self.arg = buildExpr(prob * prob)
def __str__(self):
return "cos(pi*" + str(self.arg) + ")"
def eval(self, x, y):
return math.cos(math.pi * self.arg.eval(x,y))
class Times:
def __init__(self, prob):
self.lhs = buildExpr(prob * prob)
self.rhs = buildExpr(prob * prob)
def __str__(self):
return str(self.lhs) + "*" + str(self.rhs)
def eval(self, x, y):
return self.lhs.eval(x,y) * self.rhs.eval(x,y)
def plotIntensity(exp, pixelsPerUnit = size):
canvasWidth = 2 * pixelsPerUnit + 1
canvas = Image.new("L", (canvasWidth, canvasWidth))
for py in range(canvasWidth):
for px in range(canvasWidth):
# Convert pixel location to [-1,1] coordinates
x = float(px - pixelsPerUnit) / pixelsPerUnit
y = -float(py - pixelsPerUnit) / pixelsPerUnit
z = exp.eval(x,y)
# Scale [-1,1] result to [0,255].
intensity = int(z * 127.5 + 127.5)
canvas.putpixel((px,py), intensity)
return canvas
def plotColor(exp, pixelsPerUnit = size):
redPlane = plotIntensity(exp['red'], pixelsPerUnit)
greenPlane = plotIntensity(exp['green'], pixelsPerUnit)
bluePlane = plotIntensity(exp['blue'], pixelsPerUnit)
return Image.merge("RGB", (redPlane, greenPlane, bluePlane))
exp = {"red": buildExpr(),
"green": buildExpr(),
"blue": buildExpr()}
if(debug):
print(f"seed = {seed}")
print(f"red = {exp['red']}")
print(f"green = {exp['green']}")
print(f"blue = {exp['blue']}")
return plotColor(exp, (size//2))
def psychedelic_art(req):
size = int(req.args.get('size', default=100))
assert size <= 300
img = make_image(seed=req.path, size=size)
out = BytesIO()
img.save(out, 'JPEG', quality=70)
out.seek(0)
return send_file(out, mimetype="image/jpeg")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment