1 import Image
, ImageDraw
, ImageFont
4 """ ImageLab provides a virtual workbench, on which to build images.
6 Wraps all of Image and ImageDraw, from PIL.
9 def __init__(self
, image
=None):
11 self
._history
= [image
]
14 .new("RGBA", [300,500], (0,0,0,0)) \
15 .fourcornerbox([0,0], (300,500), radius
=10, fill
="black", outline
="grey") \
17 .text([40,20], "This is a test", font
=ImageFont
.truetype("fonts/trebuc.ttf", 28)) \
19 .save("images/image-lab-test.png", "PNG") \
21 .save("images/image-lab-test2.png", "PNG") # will save a 300x500
23 test
= staticmethod(test
)
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
;
48 self
._image
= self
._history
[-i
]
49 del self
._history
[-i
:len(self
._history
)]
53 if self
._image
is not None:
54 self
._history
.append(self
._image
.copy())
56 self
._history
.append(None)
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
;
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):
134 font
= ImageFont
.truetype("fonts/arial.ttf", 12)
136 d
= ImageDraw
.Draw(self
._image
)
138 d
.text(position
, string
, font
=font
);
140 d
.text(position
, string
)
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"):
160 mark
= len(self
._history
)
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
)]