Posted by
Kenneth Sloan-2 on
Nov 28, 2019; 11:23pm
URL: http://imagej.273.s1.nabble.com/confusing-overlay-behavior-tp5022716p5022727.html
Michael-
We're getting warmer! I'm relieved to find that there *are* two Overlays stored. I was only familiar with interacting with Overlays via ImagePlus, and (naturally?) assumed that there was only one.
To answer your question - no - my code does not override ImagePlus.getCanvas().
But - yes - it does create one Overlay during construction - which is before the ImagePlus is displayed.
This was a design decision made by someone else, years ago. I'm not sure it's either correct or incorrect.
So...I'm guessing that "Duplicate" and friends will use the Overlay stored with the ImagePlus, while my high-level program is manipulating BOTH Overlays (one referenced through the ImagePlus and the other which is replaced periodically while the Canvas is active).
The gridOverlay is manipulated AFTER display of the StackWindow. Can it be that subsequent calls to
ImagePlus.setOverlay() do NOT disturb the pre-existing Overlay when there *is* a Canvas?
That actually makes sense, given the behavior.
The cursor code creates one Overlay and modifies it incrementally. That one Overlay object may be stored (by reference)
in the ImagePlus when my ImagePlus extension is created. Note that my ImagePlus extension code maintains a single Overlay variable. It is constructed, and a setOverlay() call is made BEFORE the ImagePlus is displayed. Subsequently, this code MODIFIES
that Overlay object, and does more setOverlay() calls using it. I'm guessing that the object is cached. The subsequent modifications change the one referenced by the ImagePlus - and are also stored in the Canvas (once it is displayed).
So, calls to ImagePlus.setOverlay() made AFTER the StackWindow is displayed will cause the new Overlay to be stored in the Canvas.
Calls made using the cursorOverlay (the one created by my ImagePlus extension) are stored in the Canvas - but the changes are also visible through the reference stored in the ImagePlus. Calls made by the high-level code change ONLY the Overlay stored in the Canvas. This makes the Overlay stored in the ImagePlus INVISIBLE - but does not change that version.
At first glance, I would consider this a bug. At the very least it is unexpected behavior. All of my calls are to ImagePlus.setOverlay(). I think it is reasonable for the user programmer (that would be me) to assume that there is
one Overlay associated with an ImagePlus. Instead (if this model is correct), there is one Overlay associated with the ImagePlus which is used when there is a Canvas...and another which is used when the Canvas is not present (or is not necessary for the current operation).
I'm not at all sure how to fix this - but armed with this information I suspect I can work around it. The question is: can I do that without modifying my ImagePlus extension. That looks difficult.
Can you think of any way to update the Overlay stored with the ImagePlus when there is, in fact, a Canvas?
Frankly, it seems to me that a call to ImagePlus.setOverlay() *should* update the Overlay stored with the ImagePlus (and also the one stored with the Canvas). Or, perhaps it should make the saved Overlay null WHEN the Canvas is created. I can't think of any reason to maintain inconsistent Overlays - esp. when this is not visible through the API.
Perhaps my strategy will be for my high-level code to use ImagePlus.getOverlay() to fetch the existing Overlay and modify it - instead of trying to replace it. I'll try that...tomorrow. There's a bunch of code there that needs to be smoothed out anyway.
Thanks for your help - I think you found the key fact. The rest is just a Small Matter Of Programming.
The good news is that Plugins->Utilities->Capture Image does the "right" thing, and uses the Overlay referenced by the Canvas.
So, *my* user is happy...
--
Kenneth Sloan
[hidden email]
Vision is the art of seeing what is invisible to others.
--
ImageJ mailing list:
http://imagej.nih.gov/ij/list.html