Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# GDI+ graphics WinForm
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 15-Mar-13 18:35pm
supernorb2.6K

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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.
  Permalink  
v2
Comments
supernorb at 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 at 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)

  Print Answers RSS
0 OriginalGriff 250
1 George Jonsson 175
2 Jochen Arndt 150
3 Kornfeld Eliyahu Peter 149
4 PIEBALDconsult 110
0 OriginalGriff 6,080
1 DamithSL 4,648
2 Maciej Los 4,087
3 Kornfeld Eliyahu Peter 3,624
4 Sergey Alexandrovich Kryukov 3,294


Advertise | Privacy | Mobile
Web02 | 2.8.141220.1 | Last Updated 1 May 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100