removing various old custom modules from main branch
[limo.git] / image.py
blob036f4b1b7e2c11c956323de251ef764cb27125ae
1 import Image, ImageDraw, ImageFont
3 class ImageLab:
4 """ ImageLab provides a virtual workbench, on which to build images.
5 See: test()
6 Wraps all of Image and ImageDraw, from PIL.
7 """
9 def __init__(self, image=None):
10 self._image = image
11 self._history = [image]
12 def test():
13 im = ImageLab() \
14 .new("RGBA", [300,500], (0,0,0,0)) \
15 .fourcornerbox([0,0], (300,500), radius=10, fill="black", outline="grey") \
16 .cropratio(1.0) \
17 .text([40,20], "This is a test", font=ImageFont.truetype("fonts/trebuc.ttf", 28)) \
18 .resize([200,200]) \
19 .save("images/image-lab-test.png", "PNG") \
20 .undo(2) \
21 .save("images/image-lab-test2.png", "PNG") # will save a 300x500
22 return im
23 test = staticmethod(test)
26 # creation methods
27 def new(self, mode, size): self._save(); self._image = Image.new(mode, size); return self;
28 def new(self, mode, size, color): self._save(); self._image = Image.new(mode, size, color); return self;
29 def open(self, infile): self._save(); self._image = Image.open(infile); return self;
30 def open(self, infile, mode): self._save(); self._image = Image.open(infile, mode); return self;
31 def blend(self, image1, image2, alpha): self._save(); self._image = Image.blend(image1, image2, alpha); return self;
32 def composite(self, image1, image2, mask): self._save(); self._image = Image.composite(image1, image2, mask); return self;
33 def eval(self, image, function): self._save(); self._image = Image.eval(image, function); return self;
34 def frombuffer(self, mode, size, data): self._save(); self._image = Image.frombuffer(mode, size, data); return self;
35 def frombuffer(self, mode, size, data, decoder, parameters): self._save(); self._image = Image.frombuffer(mode, size, data, decoder, parameters); return self;
36 def fromstring(self, mode, size, data): self._save(); self._image = Image.fromstring(mode, size, data); return self;
37 def fromstring(self, mode, size, data, decoder, parameters): self._save(); self._image = Image.fromstring(mode, size, data, decoder, parameters); return self;
38 def merge(self, mode, bands): self._save(); self._image = Image.merge(mode, bands); return self;
40 # custom creation methods
41 # def newfrommacro(self, mode, size, color, macro):
43 def save(self, outfile, format): self._save(); self._image.save(outfile, format); return self;
45 # history methods
46 def undo(self, i=1):
47 assert(i > 0);
48 self._image = self._history[-i]
49 del self._history[-i:len(self._history)]
50 return self
52 def _save(self):
53 if self._image is not None:
54 self._history.append(self._image.copy())
55 else:
56 self._history.append(None)
58 # data methods
59 def getbands(self): return self._image.getbands();
60 def getbbox(self): return self._image.getbbox();
61 def getcolors(self): return self._image.getcolors();
62 def getcolors(self, maxcolors): return self._image.getcolors(maxcolors);
63 def getdata(self): return self._image.getdata();
64 def getextrema(self): return self._image.getextrema();
65 def getpixel(self, xy): return self._image.getpixel(xy);
66 def histogram(self): return self._image.histogram();
67 def histogram(self, mask): return self._image.histogram(mask);
68 def split(self): return self._image.split();
69 def tell(self): return self._image.tell();
70 def tobitmap(self): return self._image.tobitmap();
71 def tostring(self): return self._image.tostring();
72 def tostring(self, encoder, parameters): return self._image.tostring(encoder, parameters);
73 def textsize(self, string, options): d = ImageDraw.Draw(self._image); ret = d.textsize(string, options); del d; return ret;
75 # manipulation methods
76 def convert(self, mode): self._save(); self._image = self._image.convert(mode); return self;
77 def convert(self, mode, matrix): self._save(); self._image = self._image.convert(mode, matrix); return self;
78 def copy(self): self._save(); self._image = self._image.copy(); return self;
79 def crop(self, box): self._save(); self._image = self._image.crop(box); return self;
80 def cropratio(self, ratio):
81 (w,h) = self._image.size
82 return self.crop([0, 0, w, int(w*ratio)])
84 def draft(self, mode, size): self._save(); self._image.draft(mode, size); return self;
85 def filter(self, filter): self._save(); self._image = self._image.filter(filter); return self;
86 def fromstring(self, data): self._save(); self._image.fromstring(data); return self;
87 def fromstring(self, data, decoder, parameters): self._save(); self._image.fromstring(data, decoder, parameters); return self;
88 def load(self): self._save(); self._image.load(); return self;
89 def offset(self, xoffset, yoffset): self._save(); self._image = self._image.offset(xoffset, yoffset); return self;
90 def paste(self, image, box): self._save(); self._image.paste(image, box); return self;
91 def paste(self, colour, box): self._save(); self._image.paste(colour, box); return self;
92 def paste(self, image, box, mask): self._save(); self._image.paste(image, box, mask); return self;
93 def paste(self, colour, box, mask): self._save(); self._image.paste(colour, box, mask); return self;
94 def point(self, table): self._save(); self._image = self._image.point(table); return self;
95 def point(self, function): self._save(); self._image = self._image.point(function); return self;
96 def point(self, table, mode): self._save(); self._image = self._image.point(table, mode); return self;
97 def point(self, function, mode): self._save(); self._image = self._image.point(function, mode); return self;
98 def putalpha(self, band): self._save(); self._image.putalpha(band); return self;
99 def putdata(self, data): self._save(); self._image.putdata(data); return self;
100 def putdata(self, data, scale, offset): self._save(); self._image.putdata(data, scale, offset); return self;
101 def putpalette(self, sequence): self._save(); self._image.putpalette(sequence); return self;
102 def putpixel(self, xy, colour): self._save(); self._image.putpixel(xy, colour); return self;
103 def resize(self, size): self._save(); self._image = self._image.resize(size, Image.ANTIALIAS); return self;
104 def rotate(self, angle, expand=False): self._save(); self._image = self._image.rotate(angle, expand=expand); return self;
105 def seek(self, frame): self._save(); self._image.seek(frame); return self;
106 def show(self): self._save(); self._image.show(); return self;
107 def thumbnail(self, size): self._save(); self._image.thumbnail(size); return self;
108 def thumbnail(self, size, filter): self._save(); self._image.thumbnail(size, filter); return self;
109 def transform(self, size, method, data): self._save(); self._image = self._image.transform(size, method, data); return self;
110 def transform(self, size, method, data, filter): self._save(); self._image = self._image.transform(size, method, data, filter); return self;
111 def transform(self, size, EXTENT, data): self._save(); self._image = self._image.transform(size, EXTENT, data); return self;
112 def transform(self, size, EXTENT, data, filter): self._save(); self._image = self._image.transform(size, EXTENT, data, filter); return self;
113 def transform(self, size, AFFINE, data): self._save(); self._image = self._image.transform(size, AFFINE, data); return self;
114 def transform(self, size, AFFINE, data, filter): self._save(); self._image = self._image.transform(size, AFFINE, data, filter); return self;
115 def transform(self, size, QUAD, data): self._save(); self._image = self._image.transform(size, QUAD, data); return self;
116 def transform(self, size, QUAD, data, filter): self._save(); self._image = self._image.transform(size, QUAD, data, filter); return self;
117 def transform(self, size, MESH, data): self._save(); self._image = self._image.transform(size, MESH, data); return self;
118 def transform(self, size, MESH, data, filter): self._save(); self._image = self._image.transform(size, MESH, data, filter); return self;
119 def transpose(self, method): self._save(); self._image = self._image.transpose(method); return self;
120 def verify(self): self._save(); self._image.verify(); return self;
122 # drawing methods
123 def arc(self, xy, start, end, outline="black"): self._save(); d = ImageDraw.Draw(self._image); d.arc(xy, start, end, outline=outline); del d; return self;
124 def bitmap(self, xy, bitmap): self._save(); d = ImageDraw.Draw(self._image); d.bitmap(xy, bitmap); del d; return self;
125 def chord(self, xy, start, end, outline="black", fill="black"): self._save(); d = ImageDraw.Draw(self._image); d.chord(xy, start, end, outline=outline, fill=fill); del d; return self;
126 def ellipse(self, xy, outline="black", fill="black"): self._save(); d = ImageDraw.Draw(self._image); d.ellipse(xy, outline=outline, fill=fill); del d; return self;
127 def line(self, xy, fill="black", width=1): self._save(); d = ImageDraw.Draw(self._image); d.line(xy, fill=fill, width=width); del d; return self;
128 def pieslice(self, xy, start, end, outline="black", fill="black"): self._save(); d = ImageDraw.Draw(self._image); d.pieslice(xy, start, end, outline=outline, fill=fill); del d; return self;
129 def point(self, xy, fill="black" ): self._save(); d = ImageDraw.Draw(self._image); d.point(xy, fill=fill); del d; return self;
130 def polygon(self, xy, outline="black", fill="black"): self._save(); d = ImageDraw.Draw(self._image); d.polygon(xy, outline=outline, fill=fill); del d; return self;
131 def rectangle(self, box,outline="black", fill="black"): self._save(); d = ImageDraw.Draw(self._image); d.rectangle(box, outline=outline, fill=fill); del d; return self;
132 def text(self, position, string, font=None):
133 if font is None:
134 font = ImageFont.truetype("fonts/arial.ttf", 12)
135 self._save()
136 d = ImageDraw.Draw(self._image)
137 if font:
138 d.text(position, string, font=font);
139 else:
140 d.text(position, string)
141 del d;
142 return self;
144 # custom drawing methods
145 def corner(self, center, corner=0, radius=5, fill="black", outline="black"):
146 return self.pieslice([center[0]-radius, center[1]-radius, center[0]+radius, center[1]+radius], corner*90, (corner*90)+90, fill=fill, outline=outline)
148 def circle(self, origin, radius, fill="black", outline="black"):
149 return self.fourcornerbox([origin[0]-radius, origin[1]-radius]\
150 , [radius*2,radius*2]\
151 , radius=radius, fill=fill, outline=outline)
153 def fourcornerbox(self, origin, size, radius=5, fill="black", outline="black"):
154 o = origin
155 (w,h) = size
156 w -= 1
157 h -= 1
158 r = radius
159 self._save()
160 mark = len(self._history)
161 ret = self\
162 .corner([o[0]+r, o[1]+r], 2, r, fill=fill, outline=outline) \
163 .corner([o[0]+w-r, o[1]+r], 3, r, fill=fill, outline=outline) \
164 .corner([o[0]+w-r, o[1]+h-r], 0, r, fill=fill, outline=outline) \
165 .corner([o[0]+r, o[1]+h-r], 1, r, fill=fill, outline=outline) \
166 .rectangle([o[0],o[1]+r,o[0]+w,o[1]+h-r], fill=fill, outline=fill) \
167 .rectangle([o[0]+r,o[1],o[0]+w-r,o[1]+h], fill=fill, outline=fill) \
168 .line([o[0]+r, o[1], o[0]+w-r, o[1]], fill=outline, width=1) \
169 .line([o[0], o[1]+r, o[0], o[1]+h-r], fill=outline, width=1) \
170 .line([o[0]+r, o[1]+h, o[0]+w-r, o[1]+h], fill=outline, width=1) \
171 .line([o[0]+w, o[1]+r, o[0]+w, o[1]+h-r], fill=outline, width=1)
172 # hide the history for these commands, so that undo will skip back over a fourcorner box in one call
173 del self._history[mark:len(self._history)]
174 return self