jscul
jscul

Reputation: 772

What's the best way to implement an "undo" feature in photo editing application?

Obviously it takes a lot of memory to store an array of a history of changes... that's how I had my application working but it just seems like there's a smarter way to go about doing this.

ArrayList<Photo> photoHistory = new ArrayList<>();
photoHistory.add(originalPhoto);
photoHistory.add(change1);
photoHistory.add(change2);

// bad implementation - lots of memory

Maybe store only an original and a current view model and keep a log of the methods/filters used? Then when a user hits 'undo' it would take the total number of changes made and run through all of them again minus one? This also seems incredibly inefficient.

I guess I'm just looking for advice on how to implement a general 'undo' function of a software application.

Upvotes: 5

Views: 1218

Answers (1)

WolfLink
WolfLink

Reputation: 3317

Here is a tip from how GIMP implements it:

GIMP's implementation of Undo is rather sophisticated. Many operations require very little Undo memory (e.g., changing visibility of a layer), so you can perform long sequences of them before they drop out of the Undo History. Some operations, such as changing layer visibility, are compressed, so that doing them several times in a row produces only a single point in the Undo History. However, there are other operations that may consume a lot of undo memory. Most filters are implemented by plug-ins, so the GIMP core has no efficient way of knowing what changed. As such, there is no way to implement Undo except by memorizing the entire contents of the affected layer before and after the operation. You might only be able to perform a few such operations before they drop out of the Undo History.

Source

So to do it as optimally as possible, you have to do different things depending on what action is being undone. Showing or hiding a layer can be represented in a neglible amount of space, but filtering the whole image might necessitate storing another copy of the whole image. However, if you only filter part of the image (or draw in a small section of the image) perhaps you only need to store that piece of the image.

Upvotes: 7

Related Questions