Hello stackoverflow,
I have a python function that takes a string s-expression like "(add (sub 10 5) 5)", where "add" and "sub" are actually image processing functions, and evaluates and creates the image represented in the string. The image processing functions take constants, variables, or other images (represented as lists of vectors), and return images represented the same way. PIL is used to convert the image represented as a list of vectors into an image file.
To evaluate the prefix notation s-expressions, I convert the s-expr to a list, reverse it, and iterate the tokens until a function is found, at which point the image processing function is performed and the resulting image replaces the function and its arguments in the list. This is done until only one element is left in the list, which is the final image.
The image processing functions are simple- most perform some mathematical operation to each of the (r,g,b) values in the image(s).
The problem is my computer comes to a standstill if I want to make decent sized images for more complex expressions. Can this be optimised to use less memory?
def createImage(self, sexpr, filename, (picWidth, picHeight)):
"""Use the image processing functions in ImgProcessing
to create an image from the procedural information
contained in the s-expression."""
img = Image.new("RGB",(picWidth,picHeight),(255,255,255))
ip = ImgProcessing(picWidth,picHeight)
# Split s-expression into list of tokens and reverse
sList = sexpr.replace("(","").replace(")","").split()
sList.reverse()
while len(sList) > 1:
for index,token in enumerate(sList):
# If token is an image processing function
if type(token) == str and self.FuncSet.has_key(token):
# If this function takes one argument
if self.FuncSet[token] == 1:
rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
"\"" + ")")
sList = sList[:index-1] + [rawImage] + sList[index+1:]
break
# If this function takes two arguments
elif self.FuncSet[token] == 2:
rawImage = eval("ip." + token + "(" + "\"" + str(sList[index-1]) +
"\"" + "," + "\"" + str(sList[index-2]) + "\"" +
")")
sList = sList[:index-2] + [rawImage] + sList[index+1:]
break
img.putdata(sList[0])
img.save(filename)