ImageJ undo notification

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

ImageJ undo notification

Jon Harman
Hi,

Just wondering if there is any way my plugin can find out if undo has
been done on an image.  I have set up my plugin to implement ImageJ's
undo command and undo works within my plugin.  My plugin can do many
different things to an image.  For the output result I create a name
that reflects what has been done to the image. So I would like to know
if the user has undone a step.

More generally I'd like to know the sequence of ImageJ commands that
have been performed on an image.  Does ImageJ keep a log of this
somewhere?  It must have some capability to do this in the macro
recorder.  My goal will be to document exactly what has been done to an
input image to get the output image.  I can keep track of  this for my
own plugin commands, but would like to also keep track of any ImageJ
commands (smoothing, sharpen, etc) that have been done to the image.

Thanks,
Jon
Reply | Threaded
Open this post in threaded view
|

Re: ImageJ undo notification

Michael Schmid
Hi Jon,

> Just wondering if there is any way my plugin can find out if
> undo has been done on an image.
In Undo.java, the whatToUndo variable is private, so you can't
use it to determine whether undo has been done or not.

I see one possibility for a workaround:

If you have a PlugInFilter that does not specify NO_CHANGES or
NO_UNDO, and you are working on a single image (not a full stack), a
snapshot (copy of the pixels) will be created when you run the filter.
If your filter really changes the image (if it is not a "null"
operation such as adding zero), the snapshot will be different
from the image after filtering, but equal to the image after
undo. So something like the following may work:
boolean undoDone = java.utils.Arrays.equals(ip.getPixels(),  
ip.getSnapshotPixels())
An easier (though not 100% safe) way would be to remember a
hashcode of the pixels array after each operation and see whether
it has changed or been reverted to the previous state.

> More generally I'd like to know the sequence of ImageJ commands
> that have been performed on an image.  Does ImageJ keep a log
> of this somewhere?
No, unless the Macro Recorder is active. As far as I understand
the Recorder.java code, the recorder has no public methods that
would allow reading what it has recorded.

Even in case we had a method like
   public String Recorder.getRecordedText()
you should not expect to get the history of an image from the
recorder: Some operations are not recorded, e.g. selecting an
image by clicking onto it. So you never know which image a
command was acting on.

For your own plugins, you can of course store a log of each
operation in the info of the ImagePlus.

Having such a feature in ImageJ would be nice, but I fear it
would be a hell of work to implement it (more than 20 source
files make calls to the Recorder).
Also, a really proper recording of the workflow would be close
to impossible. E.g., processing may need several images,
involve duplicating or the Image Calculator (or plugins)
combining images, etc.

Regards,

Michael
Reply | Threaded
Open this post in threaded view
|

Re: ImageJ undo notification

Jon Harman
Hi Michael,

I find the undo code to be pretty opaque, thanks for looking at it.

 From what you said would a simple solution be to add a method to check
whatToUndo?
Say a method like

    public static int status() {
    return whatToUndo;
        }

My code does the following to set up for undo:
Undo.setup(Undo.COMPOUND_FILTER, imp);
I guess that sets whatToUndo = COMPOUND_FILTER.
So my code could check it to see if it was "nothing" indicating that an
undo had been done.

Jon

Michael Schmid wrote:
 > Hi Jon,
 >
 >> Just wondering if there is any way my plugin can find out if
 >> undo has been done on an image.
 > In Undo.java, the whatToUndo variable is private, so you can't
 > use it to determine whether undo has been done or not.
 >
 > I see one possibility for a workaround:
 >
 > If you have a PlugInFilter that does not specify NO_CHANGES or
 > NO_UNDO, and you are working on a single image (not a full stack), a
 > snapshot (copy of the pixels) will be created when you run the filter.
 > If your filter really changes the image (if it is not a "null"
 > operation such as adding zero), the snapshot will be different
 > from the image after filtering, but equal to the image after
 > undo. So something like the following may work:
 > boolean undoDone = java.utils.Arrays.equals(ip.getPixels(),
ip.getSnapshotPixels())
 > An easier (though not 100% safe) way would be to remember a
 > hashcode of the pixels array after each operation and see whether
 > it has changed or been reverted to the previous state.
 >
 >> More generally I'd like to know the sequence of ImageJ commands
 >> that have been performed on an image.  Does ImageJ keep a log
 >> of this somewhere?
 > No, unless the Macro Recorder is active. As far as I understand
 > the Recorder.java code, the recorder has no public methods that
 > would allow reading what it has recorded.
 >
 > Even in case we had a method like
 >   public String Recorder.getRecordedText()
 > you should not expect to get the history of an image from the
 > recorder: Some operations are not recorded, e.g. selecting an
 > image by clicking onto it. So you never know which image a
 > command was acting on.
 >
 > For your own plugins, you can of course store a log of each
 > operation in the info of the ImagePlus.
 >
 > Having such a feature in ImageJ would be nice, but I fear it
 > would be a hell of work to implement it (more than 20 source
 > files make calls to the Recorder).
 > Also, a really proper recording of the workflow would be close
 > to impossible. E.g., processing may need several images,
 > involve duplicating or the Image Calculator (or plugins)
 > combining images, etc.
 >
 > Regards,
 >
 > Michael
 >
Reply | Threaded
Open this post in threaded view
|

Re: ImageJ undo notification

Michael Schmid
Hi Jon,

that is something you would have to ask Wayne for. But it is
not something that would be used very much and I fear that it
might cause problems in the future.

E.g., assume that the Undo class may change some day, say, if
"Undo" becomes undoable, so that pressing "Undo" twice means
"Redo". In that case, after "Undo", the "whatToUndo" variable
might be set to something that your code does not expect.
(e.g. after undo with whatToUndo=FILTER, it may remain FILTER)


So it might be more simple to get a hashcode of your pixels to
see whether something has changed:

(just the idea, without all the typecasting)
   pixels=(...[])ip.getPixels();
   int oldHashCode=java.util.Arrays.hashCode(pixels); //requires Java  
1.5
...process Image ...
   pixels=(...[])ip.getPixels();
   int processedHashCode=java.util.Arrays.hashCode(pixels);

..later...
   pixels=(...[])ip.getPixels();
   int presentHashCode=java.util.Arrays.hashCode(pixels);
   boolean wasUndo = presentHashCode==oldHashCode;
   boolean unchanged = presentHashCode==processedHashCode;

With Java 1.4 or earlier, wou would have to write your own
hashcode routine since pixels.hashCode() will give a hashcode
for the reference to the array, not checking the array contents.


Michael
________________________________________________________________

On 13 Jul 2007, at 02:04, Jon Harman wrote:

> Hi Michael,
>
> I find the undo code to be pretty opaque, thanks for looking at it.
> From what you said would a simple solution be to add a method to  
> check whatToUndo?
> Say a method like
>
>    public static int status() {
>    return whatToUndo;
>        }
>
> My code does the following to set up for undo:
> Undo.setup(Undo.COMPOUND_FILTER, imp);
> I guess that sets whatToUndo = COMPOUND_FILTER.
> So my code could check it to see if it was "nothing" indicating  
> that an undo had been done.
>
> Jon
>
> Michael Schmid wrote:
> > Hi Jon,
> >
> >> Just wondering if there is any way my plugin can find out if
> >> undo has been done on an image.
> > In Undo.java, the whatToUndo variable is private, so you can't
> > use it to determine whether undo has been done or not.
> >
> > I see one possibility for a workaround:
> >
> > If you have a PlugInFilter that does not specify NO_CHANGES or
> > NO_UNDO, and you are working on a single image (not a full stack), a
> > snapshot (copy of the pixels) will be created when you run the  
> filter.
> > If your filter really changes the image (if it is not a "null"
> > operation such as adding zero), the snapshot will be different
> > from the image after filtering, but equal to the image after
> > undo. So something like the following may work:
> > boolean undoDone = java.utils.Arrays.equals(ip.getPixels(),  
> ip.getSnapshotPixels())
> > An easier (though not 100% safe) way would be to remember a
> > hashcode of the pixels array after each operation and see whether
> > it has changed or been reverted to the previous state.
> >
> >> More generally I'd like to know the sequence of ImageJ commands
> >> that have been performed on an image.  Does ImageJ keep a log
> >> of this somewhere?
> > No, unless the Macro Recorder is active. As far as I understand
> > the Recorder.java code, the recorder has no public methods that
> > would allow reading what it has recorded.
> >
> > Even in case we had a method like
> >   public String Recorder.getRecordedText()
> > you should not expect to get the history of an image from the
> > recorder: Some operations are not recorded, e.g. selecting an
> > image by clicking onto it. So you never know which image a
> > command was acting on.
> >
> > For your own plugins, you can of course store a log of each
> > operation in the info of the ImagePlus.
> >
> > Having such a feature in ImageJ would be nice, but I fear it
> > would be a hell of work to implement it (more than 20 source
> > files make calls to the Recorder).
> > Also, a really proper recording of the workflow would be close
> > to impossible. E.g., processing may need several images,
> > involve duplicating or the Image Calculator (or plugins)
> > combining images, etc.
> >
> > Regards,
> >
> > Michael
> >