Personally I wouldn't go with saving a copy of the entire canvas, I would store the event such as appending somthing like this to a log history.append( 4, 2, (128, 128, 128)
the 4,2
would be the X/Y co-ords at where the user was painting/changeing the color of the tile/pixel, the (128, 128, 128)
would be the old color that tile was. So when you use the undo function you will want to make the program go to the last item in the list history[len(history)-1]
and replace the color at X/Y to (128, 128, 128)
(history[len(history)-1][2])
Like this
BLACK = (0, 0, 0)
current_color = None
#global
history = []
#global
...
def draw(event):
global history, canvas
#when a tile gets painted on
X=event.pos[0]
Y=event.pos[1]
history.append(X,Y,canvas[X][Y])
canvas[X][Y] = current_color
def undo():
global history, canvas
X = history[len(history)-1][0]
Y = history[len(history)-1][1]
color = history[len(history)-1][2]
canvas[X][Y] = color
history.pop(len(history)-1)
This way you are using a lot less ram, so you can store a lot more events.