Undo on overlay

Hello,

I am writing a macro plugin to annotate areas saved in the ROI Manager, by using an overlay over the initial image: Image>Overlay>From ROI Manager

If the user clicks in a selection, then the area of the selection is colored with:
Overlay.addSelection("", 0, color);

After an area in the overlay has been colored, is there a way to “Undo” this filling, and bring back the
transparent part of that area?

KM

Dear @kmouts,

You can set the fill color to none for all selections in an overlay with Image > Overlay > Overlay Options… (with Apply checked) or via a macro call:

run("Overlay Options...", "stroke=yellow width=0 fill=none apply");

Best,
Stefan

Dear @stelfrich,

Thanks for your reply. Indeed this command clears ALL the fillings. It would be great if the command:
Overlay.addSelection("", 0, color);
had a way to add “none” to color and bring back the transparency of the selection… Also, it is strange that if
I choose color using hex notation and adding alpha value for opacity,it merges colors with the existing overlay selection color and not only with the original image background.

By the way, does anyone know what the argument “0” means? I tried to look into the java source of
macro commands, but I only found addSelection() without any arguments.

Thanks again,

Konstantinos

Good day Konstantinos,

here is what the “commented macro functions”-doc tells us:

Overlay.addSelection
Adds the current selection to the overlay.
Overlay.addSelection(strokeColor)
Sets the stroke color (“red”, “green”, “ff8800”, etc.) of the current selection and adds it to the overlay.
Overlay.addSelection(strokeColor, strokeWidth)
Sets the stroke color (“blue”, “yellow”, “ffaa77” etc.) and stroke width of the current selection and adds it to the overlay.
Overlay.addSelection("", 0, fillColor)
Sets the fill color (“red”, “green”, etc.) of the current selection and adds it to the overlay.

Regards

Herbie

This might be because you’re adding a selection on top of the currently existing overlay, no?

This is another example where the macro language is (still) more limited than any full-fledged scripting language where you can simply interact with the Java API of the Overlay and Roi classes. For example, you can use Overlay#get(int i) to get a specified ROI from the overlay, and then Roi#setFillColor() or Roi#setStrokeColor() and Roi#setStrokeWidth() to edit any property, before running ImagePlus#updateAndDraw() to update the image display.

This Groovy script illustrates how to assign a specific color and opacity to a single given element of the overlay:

#@ ImagePlus imp
#@ ColorRGB(label="Fill color") c
#@ Integer(style=slider, min=0, max=100) opacity
#@ Integer(label="Index of overlay item to fill", value=0, persist=false) i

import java.awt.Color

ovl = imp.getOverlay()
fillColor = new Color(c.getRed(), c.getGreen(), c.getBlue(), 255*opacity/100 as int)
ovl.get(i).setFillColor(fillColor)
imp.updateAndDraw()

Input dialog:

image

Result on the blobs image:

image

1 Like

Well Jan,

once more, I think the ImageJ macro language is more capable than you expect it to be:

run( "To ROI Manager" );
idx = roiManager( "count" );
rois = Array.getSequence( idx );
for ( i=0; i < idx; i++ ) { rois[i] = d2s( 1+rois[i], 0 ); }
Dialog.create("Set Overlay Fill");
Dialog.addChoice( "Index", rois );
Dialog.addSlider( "Opacity", 0, 255, 128 );
Dialog.addSlider( "Red", 0, 255, 0 );
Dialog.addSlider( "Green", 0, 255, 0 );
Dialog.addSlider( "Blue", 0, 255, 0 );
Dialog.show();
idx = parseInt( Dialog.getChoice() ) - 1;
c = padStr( toHex( Dialog.getNumber() ) );
c = c + padStr( toHex( Dialog.getNumber() ) );
c = c + padStr( toHex( Dialog.getNumber() ) );
c = c + padStr( toHex( Dialog.getNumber() ) );
roiManager( "select", idx );
roiManager( "Set Fill Color", c );
run( "From ROI Manager" );
run( "Overlay Options...", "stroke=none width=0 fill=none" );
exit();
function padStr( hex ) {
	if ( lengthOf( hex ) < 2 ) { return "0" + hex; } else { return hex; }
}

Admitted, more code lines but easier to grasp code…

blobs

ScreenShot

blobsColorOL

Regards

Herbie

1 Like

Alright, Herbie, you beat me on this one :slight_smile:

Yes, I admit I do underrate the macro language sometimes. Thank you for this illustrative example. This is why I love this community: with all these contributions, you never stop learning and see a lot of different ways to solve tasks.

To save a few lines (admittedly not many), you could now combine the best of both worlds and use script parameters and the macro language (drawback: it’s currently lacking the possibility of a callback to get the number of ROIs in the overlay…):

#@ Integer index
#@ Integer (style=slider, min=0, max=255) opacity
#@ Integer (style=slider, min=0, max=255) red
#@ Integer (style=slider, min=0, max=255) green
#@ Integer (style=slider, min=0, max=255) blue

run( "To ROI Manager" );
idx = roiManager( "count" );
rois = Array.getSequence( idx );
for ( i=0; i < idx; i++ ) { rois[i] = d2s( 1+rois[i], 0 ); }
c = padStr( toHex( opacity ) );
c = c + padStr( toHex( red ) );
c = c + padStr( toHex( green ) );
c = c + padStr( toHex( blue ) );
roiManager( "select", index );
roiManager( "Set Fill Color", c );
run( "From ROI Manager" );
run( "Overlay Options...", "stroke=none width=0 fill=none" );
exit();
function padStr( hex ) {
	if ( lengthOf( hex ) < 2 ) { return "0" + hex; } else { return hex; }
}

Maybe, maybe not, Jan!

Your version of my code doesn’t run with plain ImageJ that I prefer for many reasons and I’m not alone.

Best

Herbie

Great!

This command is not mentioned in:Build-in commands!!
Thanks @anon96376101

Good day Konstantinos,

great that my contribution was of some help for you.

roiManager( “Set Fill Color”, c );

can be recorded (Plugins >> Marcros >> Record…) when using the ROI manager and choosing “Properties…”.

I agree that it should be included to the list of built in macroo functions.

Regards

Herbie