Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
3.33/5 (3 votes)
Do you have any efficient solution to undo changes to a Bitmap?

Here are solutions I know:

1. Save exactly a copy of the Bitmap before any change.
2. Save just the difference between the original Bitmap and the changed Bitmap, the difference is stored as an array of some structure including information about point location and point color (argb).

3. I'm seeking for.

I also know of Graphics.Save() and Graphics.Restore() methods, but I don't know much clear about what these methods can do for me, all I know is they can help us save and restore only transformations done to a Graphics object. That means changes to pixels can't be undone this way, doesn't it?


Could you please give me any efficient solution for this? If there is no solution, I will go for the second solution in my list. Thank you!

VipHaLong
Posted

1 solution

If you need to be able to perform a single Undo after a series of changes, saving the whole image is good enough. It can even be the best solution if changes are numerous. (A list of changed pixels is less compact as you need to store the coordinates as well as the old argb).

If you wand to be able to Undo every atomic change, saving every intermediate bitmap is probably overkill and accumulating the differences becomes more attractive. A one-size-fits-all solution can be to alternate full image saving (when most of the image is modified) and differences saving.

Most of the time, changes are irreversible. When you overwrite a pixel, you can't retrieve its previous value. For instance, if you apply a smoothing filter, you can't invert it to restore the exact original. That seems to imply that in case of large changes you need to keep a lot of information.

But there is a workaround trick: you can keep spaced restore points plus the list of individual transforms between them. Then, rather than working backward from the current state, you will work forward from the previous restore point, and re-apply the direct transform. This way, you trade storage for running-time (the transform list being extremely compact).

Example:
Original > Smooth > Fill a Rectangle > Invert

Successive Undo's are obtained by recomputing:
Original > Smooth > Fill a Rectangle

Original > Smooth

Original

While recomputing, you can cache all intermediate images so that all Undo's and Redo's between two restore points are fast.
 
Share this answer
 
v2
Comments
supernorb 1-May-13 7:39am    
I didn't think this question of mine could be answered by someone. Well, it's a long time ago. I chose the Second (#2) method in my list mentioned in my question for my application (a Simple Paint like MS Paint) and it seemed to work OK. I just asked this question to seek for a better solution if it does exists. I can see that your idea is great. If calculating carefully and combine with the second method of mine, they can improve the memory issue much. Thanks for sharing. However, I may try this in another project of mine. The project which I was working on when asking this question was already done successfully (I think so). :)
YDaoust 1-May-13 9:10am    
Glad that you worked it out.

This question matters to me. I am involved in image processing applications, where implementing Undo/Redo is not so trivial. As far as I know, little has been published on this topic.

Cheers.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900