img.py
'''\
Images.
classes:
Point (object)
Img (object)
Chart (Img)
XYChart (Chart)
functions:
dispatch(cmd,[args]) - Module Command Dispatch
doit() - Default function
Developer@Sonnack.com
May 2012
'''
from sys import stdout, stderr, argv
from datetime import date, timedelta
from os import path
import math, random
import Image, ImageDraw, ImageFont
from colors import *
Log = stderr
fBox = lambda xy,d: (xy[0]-int(d/2), xy[1]-int(d/2), xy[0]+int(d/2), xy[1]+int(d/2))
tAdd = lambda t1,t2: tuple(map(lambda x1,x2: x1+x2, t1, t2))
tSub = lambda t1,t2: tuple(map(lambda x1,x2: x1-x2, t1, t2))
random.seed()
fntHelvR08 = 'C:\\Python27\\Lib\\site-packages\\pilfonts\\helvR08.pil'
fntHelvR10 = 'C:\\Python27\\Lib\\site-packages\\pilfonts\\helvR10.pil'
fntHelvB08 = 'C:\\Python27\\Lib\\site-packages\\pilfonts\\helvB08.pil'
fntHelvB10 = 'C:\\Python27\\Lib\\site-packages\\pilfonts\\helvB10.pil'
class Point (object):
'''Point class.'''
def __init__ (self, x=0, y=0):
'''Create new Point instance.'''
self.x = x
self.y = y
def __str__ (self):
'''String version (a comma-separated number pair).'''
return '%f, %f' % (self.x, self.y)
def __repr__ (self):
'''Canonical representation (a tuple).'''
return (self.x, self.y)
class PieGraph (object):
def __init__ (self, data):
'''New PieGraph instance. {data=pie slice sizes}'''
tot = reduce(lambda acc,x: acc + float(x), data, 0.0)
print 'tot: ',tot
self.pieces = map(lambda x: [x, float(x)/tot, 0,0], data)
a = 0
for pc in self.pieces:
pc[2] = a
a = a + int(pc[1] * 360.0)
pc[3] = a
def draw (self, img, xy, radius):
'''New PieGraph instance. {img=Img instance, xy=location tuple}'''
bx = fBox(xy, radius)
print 'box: ',bx
for pc in self.pieces:
c = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
img.draw.pieslice(bx, pc[2],pc[3], fill=c, outline=ColorBlack)
print pc
return self
class Img (object):
'''\
Image base class.
This simple class just encapsulates the Image API in a helper object.
Note that images created with this class automatically have a three-pixel
border around them.
usage:
dims = (640, 480)
im = Img(dims)
'''
def __init__ (self, dims, bg=ColorWhite):
'''Create new Img instance with given dimensions.'''
self.dims = dims
self.im = Image.new('RGB', dims, bg)
self.draw = ImageDraw.Draw(self.im)
self.draw.rectangle((0,0)+(self.dims[0]-1,self.dims[1]-1), outline=ColorBlack)
self.draw.rectangle((1,1)+(self.dims[0]-2,self.dims[1]-2), outline=ColorDarkGray)
self.draw.rectangle((2,2)+(self.dims[0]-3,self.dims[1]-3), outline=ColorGray)
def get (self, xy):
if not (isinstance(xy,tuple) or isinstance(xy,list)):
raise TypeError,('Index must be a tuple or list! (not a "%s")' % type(xy).__name__)
if not (len(xy) == 2):
raise TypeError,('Index must have two coordinates! (not %d)' % len(xy))
if (self.dims[0] <= xy[0]) or (self.dims[1] < xy[1]):
raise IndexError,('Index out of bounds! %s' % str(xy))
return self.im.getpixel(xy)
def circle (self, xy, radius, fg, bg):
'''Draw a circle.'''
ulc = (xy[0]-radius, xy[1]-radius)
lrc = (xy[0]+radius, xy[1]+radius)
self.draw.ellipse([ulc, lrc], outline=fg, fill=bg)
return self
def show (self):
'''Display image in default viewer.'''
self.im.show()
return self
def save (self, fn, mode='PNG'):
'''Save image as a file.'''
self.im.save(fn, mode)
return self
def __str__ (self):
'''String version: format, size, mode.'''
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):
'''Canonical representation (JSON-like string).'''
s = '{Img:{format:"%s", size:%s, mode:"%s", addr:%x}}'
t = (self.im.format, str(self.im.size), self.im.mode, self.__hash__())
return s % t
class Chart (Img):
'''\
Chart Image base class.
This class encapsulates the idea of a plot area on the image.
There is a title centered across the top of the plot area.
There is an X-axis along the bottom and a Y-axis along the left.
The values provided for the axes are evenly spaced along the plot area sides.
The values may be strings or numbers (which are converted to strings).
Note that the Y-axis text is painted from top-to-bottom, so the first
value provided in the list goes at the top and the last on goes at the
axis bottom.
Currently the client must call the .make() method to generate the
plot area, title and axes. If not called, the chart just has its
gray background (making it similar to a plain image).
Clients use the .plot_ulc, .plot_lrc and .plot_dim properties to draw
directly on the chart plot area. Each property is a (x,y) tuple. The
first two define the corners; the last one defines the plot area size.
usage:
ttl = 'My Awesome Chart'
sz = (640, 480)
xa = [0, 90, 180, 270, 360]
ya = [+1, 0, -1]
im = Img(sz, ttl, xa,ya)
im.make()
'''
def __init__ (self, dims, title=None, x_axis=[], y_axis=[], bg=ColorWhite):
'''Create new Chart instance.'''
super(Chart,self).__init__(dims, ColorFaintGray)
self.font_axis = ImageFont.load(fntHelvR08)
self.font_title = ImageFont.load(fntHelvB10)
self.margin = (9,4,12,9)
self.title = title
self.x_axis = x_axis
self.y_axis = y_axis
self.plot_bg = bg
self.title_box = self.draw.textsize(self.title, font=self.font_title)
self.x_axis_box = self._calc_axis_text_size(self.x_axis)
self.y_axis_box = self._calc_axis_text_size(self.y_axis)
self.plot_ulc = (self.margin[0] + self.y_axis_box[0], self.margin[1] + self.title_box[1])
self.plot_lrc = (dims[0]-self.margin[2], dims[1]-(self.margin[3] + self.x_axis_box[1]))
self.plot_dim = tSub(self.plot_lrc, self.plot_ulc)
self.x_axis_ulc = (self.plot_ulc[0], self.plot_lrc[1])
self.x_axis_box = (self.plot_dim[0], self.x_axis_box[1])
self.y_axis_ulc = (self.margin[0] , self.plot_ulc[1])
self.y_axis_box = (self.y_axis_box[0], self.plot_dim[1])
self.title_ulc = (self.plot_ulc[0] + (int(self.plot_dim[0] / 2) - int(self.title_box[0] / 2)), self.margin[1])
print "plot:", self.plot_ulc, self.plot_lrc
def make (self):
'''Make the chart.'''
self._draw_plot_area()
self._draw_x_axis()
self._draw_y_axis()
self.draw.text(self.title_ulc, self.title, font=self.font_title, fill=ColorBlack)
return self
def _draw_plot_area (self):
'''private:Draw Plot Area.'''
self.draw.rectangle([self.plot_ulc, self.plot_lrc], outline=ColorBlack, fill=self.plot_bg)
return self
def _draw_x_axis (self):
'''private:Draw X-Axis.'''
if not self.x_axis:
return self
lrc = tAdd(self.x_axis_ulc, self.x_axis_box)
n = len(self.x_axis)
px = int(self.x_axis_box[0] / (n-1)) if 1 < n else 0
for ix,t in enumerate(self.x_axis):
s = str(t)
sz = self.draw.textsize(s, font=self.font_axis)
if ix == 0:
ulc = self.x_axis_ulc
elif ix == (n - 1):
ulc = tSub(lrc, sz)
else:
ulc = ((self.x_axis_ulc[0] + (ix * px)) - int(sz[0]/2), self.x_axis_ulc[1])
self.draw.text(ulc, s, font=self.font_axis, fill=ColorBlack)
return self
def _draw_y_axis (self):
'''private:Draw Y-Axis.'''
if not self.y_axis:
return self
lrc = tAdd(self.y_axis_ulc, self.y_axis_box)
n = len(self.y_axis)
py = int(self.y_axis_box[1] / (n-1)) if 1 < n else 0
for ix,t in enumerate(self.y_axis):
s = str(t)
sz = self.draw.textsize(s, font=self.font_axis)
if ix == 0:
ulc = (lrc[0]-sz[0], self.y_axis_ulc[1])
elif ix == (n - 1):
ulc = tSub(lrc, sz)
else:
ulc = (lrc[0]-sz[0], (self.y_axis_ulc[1] + (ix * py)) - int(sz[1]/2))
self.draw.text(ulc, s, font=self.font_axis, fill=ColorBlack)
return self
def _calc_axis_text_size (self, axis):
'''private:Calculate Axis Text Size.'''
rv = [0,0]
for t in axis:
s = str(t)
sz = self.draw.textsize(s, font=self.font_axis)
if rv[0] < sz[0]:
rv[0] = sz[0]
if rv[1] < sz[1]:
rv[1] = sz[1]
return tuple(rv)
def __repr__ (self):
'''Canonical representation (JSON-like string).'''
s = '{Chart:{parent:%s, ulc:%s, lrc:%s, plot:%s, title:"%s"}}'
t = (super(Chart,self).__repr__(), str(self.plot_ulc), str(self.plot_lrc), str(self.plot_dim), self.title)
return s % t
class XYChart (Chart):
'''\
XY Chart Image class.
This class adds the capability to draw in the plot area.
usage:
ttl = 'My Awesome Chart'
sz = (640, 480)
pz = (360, 2)
xa = [0, 90, 180, 270, 360]
ya = [+1, 0, -1]
xg = (90, 30)
yg = (1, )
im = XYChart(sz, ttl, xa,ya, xg,yg)
im.make()
'''
def __init__ (self, dims, scale, title=None, x_axis=[], y_axis=[], x_grid=(), y_grid=(), bg=ColorWhite):
'''Create new Chart. {dims=(x,y), scale=(x,y), _axis=[], _grid=(max,min)}'''
super(XYChart,self).__init__(dims, title, x_axis, y_axis, bg)
self.scale = scale
self.x_grid = x_grid
self.y_grid = y_grid
self.factor = (self.plot_dim[0] / float(self.scale[0]), self.plot_dim[1] / float(self.scale[1]))
print "factor:", self.factor
def make (self):
'''Make the Chart.'''
super(XYChart,self).make()
self._draw_x_grid()
self._draw_y_grid()
return self
def plot (self, data, color=ColorRed, width=1):
'''Draw the Chart. {data=[xy1,xy2,..]}'''
pdata = map(lambda t: (self.fx(t[0]), self.fy(t[1])), data)
self.draw.line(pdata, fill=color, width=width)
return self
def plot_vlines (self, data, color=ColorRed, width=1):
'''Draw the Chart using vertical lines.'''
yb = self.fy(0)
pdata = map(lambda t: (self.fx(t[0]), self.fy(t[1])), data)
for pt in pdata:
self.draw.line([(pt[0],yb), pt], fill=color, width=width)
def fx (self, x):
'''Factor X.'''
return self.plot_ulc[0] + (x * self.factor[0])
def fy (self, y):
'''Factor Y.'''
return self.plot_lrc[1] - (y * self.factor[1])
def _draw_x_grid (self):
'''private:Draw X Grid.'''
if not self.x_grid:
return self
if 1 < len(self.x_grid):
x = self.x_grid[1]
while x < self.scale[0]:
px = self.fx(x)
p0 = (px, self.plot_ulc[1]+1)
p1 = (px, self.plot_lrc[1]-1)
self.draw.line([p0, p1], fill=ColorGray200)
x = x + self.x_grid[1]
if 0 < len(self.x_grid):
x = self.x_grid[0]
while x < self.scale[0]:
px = self.fx(x)
p0 = (px, self.plot_ulc[1]+1)
p1 = (px, self.plot_lrc[1]-1)
self.draw.line([p0, p1], fill=ColorGray100)
x = x + self.x_grid[0]
return self
def _draw_y_grid (self):
'''private:Draw Y Grid.'''
if not self.y_grid:
return self
if 1 < len(self.y_grid):
y = self.y_grid[1]
while y < self.scale[1]:
py = self.fy(y)
p0 = (self.plot_ulc[0]+1, py)
p1 = (self.plot_lrc[0]-1, py)
self.draw.line([p0, p1], fill=ColorGray200)
y = y + self.y_grid[1]
if 0 < len(self.y_grid):
y = self.y_grid[0]
while y < self.scale[1]:
py = self.fy(y)
p0 = (self.plot_ulc[0]+1, py)
p1 = (self.plot_lrc[0]-1, py)
self.draw.line([p0, p1], fill=ColorGray100)
y = y + self.y_grid[0]
return self
def __repr__ (self):
'''Canonical representation (JSON-like string).'''
s = '{XYChart:{parent:%s, scale:%s, xgrid:%s, ygrid:%s}}'
t = (super(XYChart,self).__repr__(), str(self.scale), str(self.x_grid), str(self.y_grid))
return s % t
class BarChart (Chart):
'''Bar Chart Image class.'''
def __init__ (self, dims, y_scale, title=None, x_axis=[], y_axis=[], y_grid=(), bg=ColorWhite):
'''Create new Chart. {dims=(x,y), _axis=[], y_scale=f, y_grid=(max,min)}'''
super(BarChart,self).__init__(dims, title, x_axis, y_axis, bg)
self.y_scale = y_scale
self.y_grid = y_grid
self.y_factor = float(self.plot_dim[1]) / float(y_scale)
print "factor:", self.y_factor
def make (self):
super(BarChart,self).make()
self._draw_y_grid()
return self
def fy (self, y):
return self.plot_lrc[1] - (y * self.y_factor)
def _draw_y_grid (self):
if not self.y_grid:
return self
if 1 < len(self.y_grid):
for y in range(self.y_grid[1], self.y_scale, self.y_grid[1]):
py = self.fy(y)
p0 = (self.plot_ulc[0]+1, py)
p1 = (self.plot_lrc[0]-1, py)
self.draw.line([p0, p1], fill=(239,239,239))
if 0 < len(self.y_grid):
for y in range(self.y_grid[0], self.y_scale, self.y_grid[0]):
py = self.fy(y)
p0 = (self.plot_ulc[0]+1, py)
p1 = (self.plot_lrc[0]-1, py)
self.draw.line([p0, p1], fill=(191,191,191))
return self
def __repr__ (self):
s = '{BarChart:{parent:%s, ygrid:%s}}'
t = (super(BarChart,self).__repr__(), str(self.y_grid))
return s % t
def demo0 (*args):
sz = (640, 480)
pz = (360, 20)
xa = [0, 90, 180, 270, 360]
ya = ['+1', 0, '-1']
xg = (45, )
yg = (5, 1)
im = XYChart(sz, pz, 'Sine and Cosine', xa,ya, xg,yg)
im.make()
dda = [(x, 10 + (9 * math.sin(math.radians(float(x))))) for x in range(0,360,5)]
ddb = [(x, 10 + (9 * math.cos(math.radians(float(x))))) for x in range(0,360,5)]
im.plot(dda, ColorRed)
im.plot(ddb, ColorBlue)
im.save('demo0.png')
im.show()
return im
def demo1 (*args):
fn = 'demo1.png'
sz = (640, 480)
c1 = ( 30, 30)
c2 = (610, 30)
c3 = (610, 450)
c4 = ( 30, 450)
bx = (100, 100, sz[0]-100, sz[1]-100)
font0 = ImageFont.load(fntHelvR08)
font1 = ImageFont.load(fntHelvB08)
font2 = ImageFont.load(fntHelvB10)
im = Image.new('RGB', sz, ColorWhite)
draw = ImageDraw.Draw(im)
try:
c = (223, 223, 255)
for x in range(0, sz[0], 12):
draw.line([(x,0), (x,sz[1]-1)], fill=c)
for y in range(0, sz[1], 12):
draw.line([(0,y), (sz[0]-1,y)], fill=c)
draw.ellipse(fBox(c1,40), fill=ColorRed , outline=ColorBlack)
draw.ellipse(fBox(c2,40), fill=ColorYellow, outline=ColorBlack)
draw.ellipse(fBox(c3,40), fill=ColorGreen , outline=ColorBlack)
draw.ellipse(fBox(c4,40), fill=ColorBlue , outline=ColorBlack)
draw.rectangle(bx, fill=ColorLightGray, outline=ColorBlack)
draw.text((bx[0]+29,bx[1]+3), 'American League', font=font2, fill=(0,0,0))
draw.text((bx[0]+225,bx[1]+3), 'National League', font=font2, fill=(0,0,0))
draw.text((bx[0]+17,bx[1]+20), 'West', font=font1, fill=(0,0,0))
draw.text((bx[0]+65,bx[1]+20), 'Central', font=font1, fill=(0,0,0))
draw.text((bx[0]+128,bx[1]+20), 'East', font=font1, fill=(0,0,0))
draw.text((bx[0]+213,bx[1]+20), 'West', font=font1, fill=(0,0,0))
draw.text((bx[0]+261,bx[1]+20), 'Central', font=font1, fill=(0,0,0))
draw.text((bx[0]+324,bx[1]+20), 'East', font=font1, fill=(0,0,0))
x = bx[0] + 12
y = bx[1] + 36
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_sea_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_oak_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_ana_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_tex_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_hou_36x32.png")
im.paste(icon, (x,y))
x = x + int(icon.size[0] * 1.5)
y = bx[1] + 36
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_min_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_cws_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_det_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_cle_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_kc_36x32.png")
im.paste(icon, (x,y))
x = x + int(icon.size[0] * 1.5)
y = bx[1] + 36
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_tor_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_bos_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_nyy_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_bal_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_tb_36x32.png")
im.paste(icon, (x,y))
x = x + int(icon.size[0] * 2.5)
y = bx[1] + 36
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_sf_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_la_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_sd_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_ari_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_col_36x32.png")
im.paste(icon, (x,y))
x = x + int(icon.size[0] * 1.5)
y = bx[1] + 36
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_mil_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_chc_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_pit_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_cin_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_stl_36x32.png")
im.paste(icon, (x,y))
x = x + int(icon.size[0] * 1.5)
y = bx[1] + 36
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_nym_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_phi_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_was_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_atl_36x32.png")
im.paste(icon, (x,y))
y = y + icon.size[1]
icon = Image.open(r"C:\Users\Chris\Pictures\BB\icons\im_logo_mia_36x32.png")
im.paste(icon, (x,y))
draw.arc(fBox((sz[0]-1, sz[1]-1), 12), 190,260, fill=ColorDarkBlue)
draw.arc(fBox((sz[0]-1, sz[1]-1), 15), 190,260, fill=ColorDarkBlue)
draw.arc(fBox((sz[0]-1, sz[1]-1), 19), 190,260, fill=ColorDarkBlue)
draw.arc(fBox((sz[0]-1, sz[1]-1), 24), 190,260, fill=ColorDarkBlue)
draw.rectangle((0,0, sz[0]-1,sz[1]-1), outline=ColorBlack)
draw.rectangle((1,1, sz[0]-2,sz[1]-2), outline=ColorDarkGray)
draw.rectangle((2,2, sz[0]-3,sz[1]-3), outline=ColorGray)
draw.rectangle((3,3, sz[0]-4,sz[1]-4), outline=ColorLightGray)
s = 'Chris@Sonnack.com'
b = draw.textsize(s, font=font1)
x = sz[0] - (b[0]+50)
y = sz[1] - (b[1]+5)
draw.text((x,y), s, font=font1, fill=(127,127,127))
except Exception as e:
print >> stderr, e
return e
finally:
del draw
im.save(fn, 'PNG')
im.show()
return im
ChartMax = (164, 120)
ChartMul = (2, 1)
ChartSize = (ChartMax[0] * ChartMul[0], (1 + (2 * ChartMax[1])) * ChartMul[1])
ChartDims = (ChartSize[0]+30, ChartSize[1]+30)
ChartULC = (20, 10)
ChartLRC = (ChartULC[0]+ChartSize[0], ChartULC[1]+ChartSize[1])
ChartX = lambda x: ChartULC[0] + (2 * int(x))
ChartY = lambda y: (ChartULC[1] + ChartMax[1]) - int(y)
def demo2 (*args):
'''\
Generate a Chart.
'''
fn = 'demo2.png'
x0 = ChartX(1)
x1 = ChartX(ChartMax[0]-1)
zy = ChartY(0)
im = Image.new('RGB', ChartDims, ColorWhite)
draw = ImageDraw.Draw(im)
try:
draw.rectangle((0,0)+(ChartDims[0]-1,ChartDims[1]-1), outline=ColorBlack)
draw.rectangle((2,2)+(ChartDims[0]-3,ChartDims[1]-3), outline=ColorDarkGray)
draw.rectangle(ChartULC+ChartLRC, fill=ColorLightGray, outline=ColorBlack)
m = int(20)
f = ChartMax[1] / float(m)
for n in range(1, m):
yp = ChartY(f * +n)
yn = ChartY(f * -n)
c = ColorGray if n % 10 else ColorDarkGray
draw.line([(x0,yp), (x1,yp)], width=1, fill=c)
draw.line([(x0,yn), (x1,yn)], width=1, fill=c)
draw.line([(x0,zy), (x1,zy)], width=1, fill=ColorBlack)
for x in range(ChartMax[0]-1):
px = ChartX(1+x)
py = ChartY(int(80 * math.sin(math.radians((x/float(ChartMax[0])) * 360.0))))
draw.point((px, py), fill=ColorRed)
except Exception as e:
print >> stderr, e
return e
finally:
del draw
im.save(fn, 'PNG')
im.show()
return im
class GameCounter (object):
def __init__ (self):
self.games = 0
def get (self):
if random.random() < 0.5:
self.games = self.games + 1
return self.games
def demo3 (*args):
fn = 'demo3.png'
sz = (640, 480)
pz = (162, 100)
xa = [0, 27, 54, 81, 108, 135, 162]
ya = [100, 75, 50, 25, 0]
xg = (27, 3)
yg = (25, 5)
im = XYChart(sz, pz, 'Twins Team BA - 2013', xa,ya, xg,yg)
im.make()
gc = GameCounter()
dd = [(0,0)] + [(1+x, gc.get()) for x in range(81)]
im.plot(dd, ColorRed)
gc = GameCounter()
dd = [(0,0)] + [(1+x, gc.get()) for x in range(162)]
im.plot(dd, ColorBlue)
gc = GameCounter()
dd = [(0,0)] + [(1+x, gc.get()) for x in range(162)]
im.plot(dd, (0,127,0))
im.save(fn)
im.show()
return im
def demo4 (*args):
sz = (640, 480)
pz = (100, 100)
xa = [0.0, .25, .50, .75, 1.0]
ya = ['1.0', .50, '0.0']
xg = (25, 5)
yg = (25, 5)
F = lambda x: 100 * ((float(100-x)/100.0) ** 2)
im = XYChart(sz, pz, 'Curve', xa,ya, xg,yg)
im.make()
dda = [(x, F(x)) for x in range(100)]
im.plot(dda, ColorRed)
im.save('demo4.png')
im.show()
return im
def dispatch (cmd, *args):
'''\
Dispatch Command.
usage:
module_name {command} {arguments}
commands:
demo0 - Demo #0 - Img class test
demo1 - Demo #1 - Hello, World!
demo2 - Demo #2 - A Chart
main - Default function
'''
print 'command:', cmd
if cmd == 'demo0':
return demo0(*args)
if cmd == 'demo1':
return demo1(*args)
if cmd == 'demo2':
return demo2(*args)
if cmd == 'demo3':
return demo3(*args)
if cmd == 'demo4':
return demo4(*args)
if (len(cmd) == 0) or (cmd == 'main') or (cmd == 'default'):
return demo0(*args)
return None
if __name__ == '__main__':
print 'autorun:', argv[0]
cmnd = argv[1] if 1 < len(argv) else 'demo4'
args = argv[2:] if 2 < len(argv) else []
obj = dispatch(cmnd, *args)
if obj:
print type(obj)
'''eof'''