2
# The Python Imaging Library
5
# a simple math add-on for the Python Imaging Library
8
# 1999-02-15 fl Original PIL Plus release
9
# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6
10
# 2005-09-12 fl Fixed int() and float() for Python 2.4.1
12
# Copyright (c) 1999-2005 by Secret Labs AB
13
# Copyright (c) 2005 by Fredrik Lundh
15
# See the README file for information on usage and redistribution.
24
return isinstance(v, type(0)) or isinstance(v, type(0.0))
27
# wraps an image operand, providing standard operators
29
def __init__(self, im):
32
def __fixup(self, im1):
33
# convert image to suitable mode
34
if isinstance(im1, _Operand):
35
# argument was an image.
36
if im1.im.mode in ("1", "L"):
37
return im1.im.convert("I")
38
elif im1.im.mode in ("I", "F"):
41
raise ValueError, "unsupported mode: %s" % im1.im.mode
43
# argument was a constant
44
if _isconstant(im1) and self.im.mode in ("1", "L", "I"):
45
return Image.new("I", self.im.size, im1)
47
return Image.new("F", self.im.size, im1)
49
def apply(self, op, im1, im2=None, mode=None):
50
im1 = self.__fixup(im1)
53
out = Image.new(mode or im1.mode, im1.size, None)
56
op = getattr(_imagingmath, op+"_"+im1.mode)
57
except AttributeError:
58
raise TypeError, "bad operand type for '%s'" % op
59
_imagingmath.unop(op, out.im.id, im1.im.id)
62
im2 = self.__fixup(im2)
63
if im1.mode != im2.mode:
64
# convert both arguments to floating point
65
if im1.mode != "F": im1 = im1.convert("F")
66
if im2.mode != "F": im2 = im2.convert("F")
67
if im1.mode != im2.mode:
68
raise ValueError, "mode mismatch"
69
if im1.size != im2.size:
70
# crop both arguments to a common size
71
size = (min(im1.size[0], im2.size[0]),
72
min(im1.size[1], im2.size[1]))
73
if im1.size != size: im1 = im1.crop((0, 0) + size)
74
if im2.size != size: im2 = im2.crop((0, 0) + size)
75
out = Image.new(mode or im1.mode, size, None)
77
out = Image.new(mode or im1.mode, im1.size, None)
78
im1.load(); im2.load()
80
op = getattr(_imagingmath, op+"_"+im1.mode)
81
except AttributeError:
82
raise TypeError, "bad operand type for '%s'" % op
83
_imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id)
87
def __nonzero__(self):
88
# an image is "true" if it contains at least one non-zero pixel
89
return self.im.getbbox() is not None
91
return self.apply("abs", self)
95
return self.apply("neg", self)
98
def __add__(self, other):
99
return self.apply("add", self, other)
100
def __radd__(self, other):
101
return self.apply("add", other, self)
102
def __sub__(self, other):
103
return self.apply("sub", self, other)
104
def __rsub__(self, other):
105
return self.apply("sub", other, self)
106
def __mul__(self, other):
107
return self.apply("mul", self, other)
108
def __rmul__(self, other):
109
return self.apply("mul", other, self)
110
def __div__(self, other):
111
return self.apply("div", self, other)
112
def __rdiv__(self, other):
113
return self.apply("div", other, self)
114
def __mod__(self, other):
115
return self.apply("mod", self, other)
116
def __rmod__(self, other):
117
return self.apply("mod", other, self)
118
def __pow__(self, other):
119
return self.apply("pow", self, other)
120
def __rpow__(self, other):
121
return self.apply("pow", other, self)
124
def __invert__(self):
125
return self.apply("invert", self)
126
def __and__(self, other):
127
return self.apply("and", self, other)
128
def __rand__(self, other):
129
return self.apply("and", other, self)
130
def __or__(self, other):
131
return self.apply("or", self, other)
132
def __ror__(self, other):
133
return self.apply("or", other, self)
134
def __xor__(self, other):
135
return self.apply("xor", self, other)
136
def __rxor__(self, other):
137
return self.apply("xor", other, self)
138
def __lshift__(self, other):
139
return self.apply("lshift", self, other)
140
def __rshift__(self, other):
141
return self.apply("rshift", self, other)
144
def __eq__(self, other):
145
return self.apply("eq", self, other)
146
def __ne__(self, other):
147
return self.apply("ne", self, other)
148
def __lt__(self, other):
149
return self.apply("lt", self, other)
150
def __le__(self, other):
151
return self.apply("le", self, other)
152
def __gt__(self, other):
153
return self.apply("gt", self, other)
154
def __ge__(self, other):
155
return self.apply("ge", self, other)
158
def imagemath_int(self):
159
return _Operand(self.im.convert("I"))
160
def imagemath_float(self):
161
return _Operand(self.im.convert("F"))
164
def imagemath_equal(self, other):
165
return self.apply("eq", self, other, mode="I")
166
def imagemath_notequal(self, other):
167
return self.apply("ne", self, other, mode="I")
169
def imagemath_min(self, other):
170
return self.apply("min", self, other)
171
def imagemath_max(self, other):
172
return self.apply("max", self, other)
174
def imagemath_convert(self, mode):
175
return _Operand(self.im.convert(mode))
178
for k, v in globals().items():
179
if k[:10] == "imagemath_":
183
# Evaluates an image expression.
185
# @param expression A string containing a Python-style expression.
186
# @keyparam options Values to add to the evaluation context. You
187
# can either use a dictionary, or one or more keyword arguments.
188
# @return The evaluated expression. This is usually an image object,
189
# but can also be an integer, a floating point value, or a pixel
190
# tuple, depending on the expression.
192
def eval(expression, _dict={}, **kw):
194
# build execution namespace
198
for k, v in args.items():
200
args[k] = _Operand(v)
203
out =__builtin__.eval(expression, args)
206
except AttributeError: