1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
| import Image
import ImageDraw
import random
def GetRandomColor(mode):
"""Chooses a random color based on the cloud mode"""
if (mode=="AllColors" or mode==0):
return dict(((c, random.randint(0,255)) for c in cloud.colors))
elif (mode=="Gray" or mode==1):
c = random.randint(0,255)
color = { 'r':c, 'g': c, 'b': c }
return color
elif (mode=="BlackAndWhite" or mode==2):
c = random.randint(0,1)*255
color = { 'r':c, 'g': c, 'b': c }
return color
class Pixel(object):
"""Manages pixesl for the cloud. Holds color and position information"""
def __init__(self, x, y):
self.r = self.g = self.b = 0
self.coords = (x,y)
def SetColor(self, color, draw):
"""Sets the color of this pixel and draws itself using the image draw object passed in"""
self.r = color['r']
self.g = color['g']
self.b = color['b']
draw.point(self.coords, fill = "rgb(" + str(self.r) + "," + str(self.g) + "," + str(self.b) + ")")
class Cloud(object):
"""Draws a cloud object by repeatedly blending adjecent pixels in a grid of colors"""
dirs = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1))
colors = ('r', 'g', 'b')
def __init__(self, imgSizeX = 100, imgSizeY = 100, mutationsPerFrame = 0):
"""Build list of pixels"""
self.pixels = [ Pixel(x,y) for x in range(imgSizeX) for y in range(imgSizeY)]
if mutationsPerFrame == 0:
mutationsPerFrame = (imgSizeX * imgSizeY) / 10
self.mutationsPerFrame = mutationsPerFrame
self.imgSize = (imgSizeX, imgSizeY)
self.img = Image.new("RGB",self.imgSize)
self.draw = ImageDraw.Draw(self.img)
def Save(self, name):
"""Save image"""
self.img.save(name+".png","PNG")
def ColorSquare(self, at, squareSize=(10,10), mode=0, color=None):
"""Add a square of color defined by at and squareSize"""
if color == None:
color = GetRandomColor(mode)
edgeRanges = [range(start,start+d) for start, d in zip(at,squareSize) ]
for pixel in (self.__Pixel(x,y) for x in edgeRanges[0] ...
for y in edgeRanges[1] if x < self.imgSize[0] and y < self.imgSize[1]):
pixel.SetColor(color,self.draw)
def ColorRandomGrid(self,mode=0, stepSize=(10,10)):
"""Fills the image in with a grid based on the cloud mode"""
for coord in ( (x,y) for x in range(0, self.imgSize[0],...
stepSize[0]) for y in range(0, self.imgSize[1], stepSize[1])):
self.ColorSquare(coord, stepSize, mode)
def __SetPixelColor(self, coord, color):
"""Set color of one pixel"""
pixel = self.__Pixel(*coord)
pixel.SetColor(color, self.draw)
def Run(self, frames):
map(self.__RunOneFrame, range(frames))
def __RunOneFrame(self,frame):
for i in range(self.mutationsPerFrame):
self.__DoOneMutation()
self.Save("frame_"+str(frame))
def __DoOneMutation(self):
"""Picks a random pixel, then one of its neighbors,
finds the average color between them and sets them both to that color"""
randomCoord = [random.randint(0,i-1) for i in self.imgSize]
randomPixel = self.__Pixel(randomCoord[0],randomCoord[1])
pixels = ( randomPixel, self.__GetNeighbor(randomPixel))
newColor = {'r': 0, 'g': 0, 'b': 0}
for pixel in pixels:
for c in Cloud.colors:
newColor[c] += pixel.__dict__[c] / 2
for pixel in pixels:
pixel.SetColor(newColor, self.draw)
def __GetNeighbor(self, pixel):
randomDir = random.choice(Cloud.dirs)
neighborCoord = [ (x+y) % m for x,y,m in zip(pixel.coords, randomDir, self.imgSize) ]
return self.__Pixel(neighborCoord[0], neighborCoord[1])
def __Pixel(self,x,y):
"""Gets a pixel from the the pixels list by coordinate"""
return self.pixels[x*self.imgSize[1] + y]
if __name__ == "__main__":
cloud = Cloud(300,300)
cloud.ColorRandomGrid("BlackAndWhite")
cloud.Run(1500) |