70 lines
1.8 KiB
Python
70 lines
1.8 KiB
Python
from PIL import Image
|
|
import numpy
|
|
import numba
|
|
|
|
@numba.jit(nopython=True)
|
|
def _hilbertMap(n, size):
|
|
# https://en.wikipedia.org/wiki/Hilbert_curve
|
|
def rot(n, x, y, rx, ry):
|
|
if ry == 0:
|
|
if rx == 1:
|
|
x = n-1 - x
|
|
y = n-1 - y
|
|
|
|
x, y = y, x
|
|
|
|
return (x, y)
|
|
|
|
x, y = (0, 0)
|
|
t = n
|
|
s = 1
|
|
while (s < size):
|
|
rx = 1 & int(t / 2)
|
|
ry = 1 & (t ^ rx)
|
|
x, y = rot(s, x, y, rx, ry)
|
|
x += s * rx
|
|
y += s * ry
|
|
t = int(t / 4)
|
|
s *= 2
|
|
|
|
return x, y
|
|
|
|
class imggen:
|
|
x, y = (0,0)
|
|
imgraw = None
|
|
|
|
def __init__(self, size):
|
|
if size % 2 != 0:
|
|
raise ValueError("Size needs to be divisible by 2")
|
|
|
|
self.x = int(pow(2, size/2))
|
|
self.y = self.x
|
|
|
|
self.imgraw = numpy.zeros((self.x, self.y, 3), dtype=numpy.uint8)
|
|
|
|
|
|
def colorRange(self, start, end, color):
|
|
for p in range(start, end+1):
|
|
x, y = _hilbertMap(p, self.x)
|
|
self.imgraw[x, y] = color
|
|
|
|
def saveImage(self, path, scale=1):
|
|
img = Image.fromarray(self.imgraw, mode="RGB")
|
|
img = img.resize([self.x * scale, self.y * scale], Image.NEAREST)
|
|
img.save(path)
|
|
|
|
def showImage(self, scale=1):
|
|
img = Image.fromarray(self.imgraw, mode="RGB")
|
|
img = img.resize([self.x * scale, self.y * scale], Image.NEAREST)
|
|
img.show()
|
|
|
|
def clear(self, color=(0,0,0)):
|
|
self.imgraw = numpy.full((self.x, self.y, 3), color, dtype=numpy.uint8)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
gen = imggen(24)
|
|
gen.clear((255, 255, 255))
|
|
gen.colorRange(0, pow(2, 22), (73, 255, 51))
|
|
gen.showImage() |