Skip to content

Instantly share code, notes, and snippets.

@nst
Last active February 27, 2023 07:10
Show Gist options
  • Save nst/3dc5378399678be7eb297ef18580025e to your computer and use it in GitHub Desktop.
Save nst/3dc5378399678be7eb297ef18580025e to your computer and use it in GitHub Desktop.
Reproducing Benjamin Kovach's art with pycairo
#!/usr/bin/env python
# Author: Nicolas Seriot
# Date: 2018-03-17
# Description: Reproducing Benjamin Kovach's art with pycairo
# https://www.kovach.me/Generating_artwork_with_Haskell.html
# Output: http://seriot.ch/visualization/kovach_pycairo.png
# Gist: https://gist.github.com/nst/3dc5378399678be7eb297ef18580025e
import cairo
import os
import random
from random import randint
random.seed(0)
NB_CELLS = 26
CELL_W = 48
CELL_H = 48
SPACE = 6
NOISE = 3
CANVAS_MARGIN = 120
LINE_WIDTH = 4.0
COLOR_BACKGROUND = (239/255.0, 246/255.0, 213/255.0) # background light green
COLOR_1 = (215/255.0, 68/255.0, 80/255.0) # dark red
COLOR_2 = (220/255.0, 240/255.0, 180/255.0) # light green
COLOR_3 = (229/255.0, 153/255.0, 137/255.0) # light red
COLOR_4 = (29/255.0, 40/255.0, 38/255.0) # almost black
CANVAS_W = CELL_W * NB_CELLS + 2 * CANVAS_MARGIN
CANVAS_H = CELL_H * NB_CELLS + 2 * CANVAS_MARGIN
def noisy_quad(CELL_W, CELL_H, MARGIN, NOISE):
"""
a-b
| |
c-d
"""
a = (MARGIN , MARGIN)
b = (a[0] + CELL_W - 2*MARGIN, a[1])
c = (a[0] , a[1] + CELL_W-2 * MARGIN)
d = (c[0] + CELL_W - 2*MARGIN, c[1])
return [(x + randint(NOISE * -1, NOISE), y + randint(NOISE * -1, NOISE))
for (x,y) in (a, b, d, c)]
def draw_quad(c, origin_x, origin_y, quad, color, fill):
c.save()
c.set_source_rgb(*color)
c.translate(origin_x, origin_y)
[c.line_to(x,y) for (x,y) in quad]
c.close_path()
if fill:
c.fill()
c.stroke()
c.restore()
def image():
img = cairo.ImageSurface(cairo.FORMAT_ARGB32, CANVAS_W, CANVAS_H)
c = cairo.Context(img)
c.set_source_rgb(*COLOR_BACKGROUND)
c.rectangle(0, 0, CANVAS_W, CANVAS_H)
c.fill()
c.set_line_width(LINE_WIDTH)
origins = [(CANVAS_MARGIN + row * CELL_W, CANVAS_MARGIN + col * CELL_H)
for row in range(NB_CELLS) for col in range(NB_CELLS)
if randint(0,2) > 0]
for (x,y) in origins:
quad_points = noisy_quad(CELL_W, CELL_H, SPACE, NOISE)
color = random.choice([COLOR_1, COLOR_2, COLOR_3, COLOR_4])
draw_quad(c, x, y, quad_points, color, fill=randint(0,1)==0)
return img
img = image()
FILE_NAME = "kovach_pycairo.png"
img.write_to_png(FILE_NAME)
os.system("open -a Safari %s" % FILE_NAME)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment