maze_img.py
'''Maze Image Class.
Coder@Sonnack.com
September 16, 2014
'''
from sys import argv
from PIL import Image, ImageDraw
from maze_obj import MazeObject
import colors
class MazeImage (object):
'''|
Maze Image class.
properties:
mz - Maze object
im - Image object
draw - ImageDraw object
pixels - Pixel dimensions of image
pmin,pmax - ULC,LRC of Maze plot area
p0,p1 - ULC,LRC of current cell
methods:
draw_maze ()
show ()
save (fn, mode='PNG')
set_current_cell (row, col) - required first before using paint methods
paint_cell (color) - set cell color
paint_north_wall () - set cell north wall
paint_east_wall () - set cell east wall
paint_south_wall () - set cell south wall
paint_west_wall () - set cell west wall
str(obj) - properties string
repr(obj) - JSON-like string
'''
HorzSpace = 20
VertSpace = 20
WallColor = colors.ColorBlack
def __init__ (self, mz):
'''Create new Maze Image instance. NOTE: x=cols, y=rows!'''
self.mz = mz
self.pixels = (self.HorzSpace * (self.mz.dims[1]+2), self.VertSpace * (self.mz.dims[0]+2))
self.pmin = (self.HorzSpace, self.VertSpace)
self.pmax = (self.pixels[0] - self.HorzSpace, self.pixels[1] - self.VertSpace)
self.p0 = (self.pmin[0] , self.pmin[1])
self.p1 = (self.pmin[0]+self.HorzSpace, self.pmin[1]+self.VertSpace)
self.im = Image.new('RGB', self.pixels, colors.ColorWhite)
self.draw = ImageDraw.Draw(self.im)
self.draw.rectangle((0,0)+(self.pixels[0]-1,self.pixels[1]-1), outline=colors.ColorBlack)
self.draw.rectangle((1,1)+(self.pixels[0]-2,self.pixels[1]-2), outline=colors.ColorGray100)
self.draw.rectangle((2,2)+(self.pixels[0]-3,self.pixels[1]-3), outline=colors.ColorGray200)
for ix in range(1, self.mz.dims[1]):
pp = ix * self.HorzSpace
self.draw.line([(self.pmin[0]+pp, self.pmin[1]), (self.pmin[0]+pp, self.pmax[1])], fill=colors.ColorLightBlue)
for ix in range(1, self.mz.dims[0]):
pp = ix * self.VertSpace
self.draw.line([(self.pmin[0], self.pmin[1]+pp), (self.pmax[0], self.pmin[1]+pp)], fill=colors.ColorLightBlue)
for row in range(1, self.mz.dims[0]+2):
py = row * self.VertSpace
for col in range(1, self.mz.dims[1]+2):
px = col * self.HorzSpace
self.draw.rectangle((px-1,py-1)+(px+1,py), fill=colors.ColorBlack, outline=colors.ColorBlack)
self.draw.line([(self.pmin[0], self.pmin[1]), (self.pmax[0], self.pmin[1])], fill=(192,192,192), width=2)
self.draw.line([(self.pmin[0], self.pmax[1]), (self.pmax[0], self.pmax[1])], fill=(192,192,192), width=2)
self.draw.line([(self.pmin[0], self.pmin[1]), (self.pmin[0], self.pmax[1])], fill=(192,192,192), width=2)
self.draw.line([(self.pmax[0], self.pmin[1]), (self.pmax[0], self.pmax[1])], fill=(192,192,192), width=2)
cell_colors = [colors.ColorWhite, (96,96,128), colors.ColorRed, colors.ColorGreen, (224,224,224)]
def draw_maze (self):
'''Draw a maze.'''
for row in range(self.mz.dims[0]):
for col in range(self.mz.dims[1]):
v = self.mz.cell(row, col)
if 0 < v:
c = self.cell_colors[v % len(self.cell_colors)]
self.set_current_cell(row, col)
self.paint_cell(c)
for row in range(self.mz.dims[0]):
for col in range(self.mz.dims[1]):
self.set_current_cell(row, col)
if self.mz.wall_n(row, col):
self.paint_north_wall()
if self.mz.wall_w(row, col):
self.paint_west_wall()
if self.mz.wall_e(row, col):
self.paint_east_wall()
for col in range(self.mz.dims[1]):
self.set_current_cell(row, col)
if self.mz.wall_s(row, col):
self.paint_south_wall()
def set_current_cell (self, row, col):
'''Set current cell for drawing operations.'''
if (row < 0) or (self.mz.dims[0] <= row):
raise Exception("Row is out of bounds!")
if (col < 0) or (self.mz.dims[1] <= col):
raise Exception("Col is out of bounds!")
cx = self.pmin[0] + (col * self.HorzSpace)
cy = self.pmin[1] + (row * self.VertSpace)
self.p0 = (cx,cy)
self.p1 = (cx+self.HorzSpace, cy+self.VertSpace)
def paint_cell (self, color):
self.draw.rectangle([self.p0, self.p1], fill=color, outline=colors.ColorBlack)
def paint_north_wall (self):
'''Draw north wall in current cell.'''
self.draw.line([(self.p0[0], self.p0[1]), (self.p1[0], self.p0[1])], fill=self.WallColor, width=2)
def paint_south_wall (self):
'''Draw south wall in current cell.'''
self.draw.line([(self.p0[0], self.p1[1]), (self.p1[0], self.p1[1])], fill=self.WallColor, width=2)
def paint_west_wall (self):
'''Draw west wall in current cell.'''
self.draw.line([(self.p0[0], self.p0[1]), (self.p0[0], self.p1[1])], fill=self.WallColor, width=2)
def paint_east_wall (self):
'''Draw east wall in current cell.'''
self.draw.line([(self.p1[0], self.p0[1]), (self.p1[0], self.p1[1])], fill=self.WallColor, width=2)
def show (self):
self.im.show()
return self
def save (self, fn, mode='PNG'):
self.im.save(fn, mode)
return self
def __str__ (self):
s = '%s (%d,%d) %s'
t = (self.im.format, self.im.size[0], self.im.size[1], self.im.mode)
return s % t
def __repr__ (self):
s = '{MazeImage:{format:"%s", size:%s, mode:"%s", addr:%x}}'
t = (self.im.format, str(self.im.size), self.im.mode, self.__hash__())
return s % t
if __name__ == '__main__':
print('autorun: %s' % argv[0])
mz = MazeObject(12, 16)
mi = MazeImage(mz)
mi.set_current_cell(1,0)
mi.paint_north_wall()
mi.paint_west_wall()
mi.set_current_cell(1,1)
mi.paint_cell(colors.ColorLightRed)
mi.paint_north_wall()
mi.paint_east_wall()
mi.paint_south_wall()
mi.paint_west_wall()
mi.set_current_cell(1,2)
mi.paint_north_wall()
mi.set_current_cell(0,2)
mi.paint_north_wall()
mi.paint_west_wall()
mi.set_current_cell(2,2)
mi.paint_west_wall()
mi.show()
mi.save('maze_img.png')
'''eof'''