Skip to content

Commit

Permalink
2024.09.07 (1.54k19; Overlay positions)
Browse files Browse the repository at this point in the history
  • Loading branch information
rasband committed Sep 7, 2024
1 parent ccd0b31 commit 10e9086
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 49 deletions.
2 changes: 1 addition & 1 deletion ij/ImageJ.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public class ImageJ extends Frame implements ActionListener,

/** Plugins should call IJ.getVersion() or IJ.getFullVersion() to get the version string. */
public static final String VERSION = "1.54k";
public static final String BUILD = "16";
public static final String BUILD = "19";
public static Color backgroundColor = new Color(237,237,237);
/** SansSerif, 12-point, plain font. */
public static final Font SansSerif12 = new Font("SansSerif", Font.PLAIN, 12);
Expand Down
44 changes: 28 additions & 16 deletions ij/Undo.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public class Undo {
public static final int OVERLAY_ADDITION = 7;
public static final int ROI = 8;
public static final int MACRO = 9;
/** Undo of overlay modification */
public static final int OVERLAY = 10;

private static int whatToUndo = NOTHING;
private static int imageID;
Expand All @@ -34,6 +36,7 @@ public class Undo {
private static double displayRangeMin, displayRangeMax;
private static LUT lutCopy;
private static Overlay overlayCopy;
private static int overlayImageID;

public static void setup(int what, ImagePlus imp) {
if (imp==null) {
Expand Down Expand Up @@ -81,18 +84,23 @@ public static void setup(int what, ImagePlus imp) {
roiCopy.setImage(null);
} else
whatToUndo = NOTHING;
} else if (what==OVERLAY) {
saveOverlay(imp);
} else {
ipCopy = null;
ImageProcessor ip = imp.getProcessor();
//ImageProcessor ip = imp.getProcessor();
//lutCopy = (LUT)ip.getLut().clone();
}
}


/** This function should be called from PlugInFilters that modify the overlay prior to the operation.
* For the type 'FILTER', undo of overlays requires that the modified image also has an overlay. */
public static void saveOverlay(ImagePlus imp) {
Overlay overlay = imp!=null?imp.getOverlay():null;
if (overlay!=null)
if (overlay!=null) {
overlayCopy = overlay.duplicate();
else
overlayImageID = imp.getID();
} else
overlayCopy = null;
}

Expand All @@ -114,7 +122,7 @@ public static void undo() {
ImagePlus imp = WindowManager.getCurrentImage();
if (IJ.debugMode) IJ.log("Undo.undo: "+ whatToUndo+" "+imp+" "+impCopy);
if (imp==null || imageID!=imp.getID()) {
if (imp!=null && !IJ.macroRunning()) { // does image still have an undo buffer?
if (imp!=null && !IJ.macroRunning()) { // does foreground image still have an undo buffer?
ImageProcessor ip2 = imp.getProcessor();
ip2.swapPixelArrays();
imp.updateAndDraw();
Expand All @@ -124,7 +132,7 @@ public static void undo() {
}
switch (whatToUndo) {
case FILTER:
undoOverlay(imp);
undoOverlay(imp, true);
ImageProcessor ip = imp.getProcessor();
if (ip!=null) {
if (!IJ.macroRunning()) {
Expand All @@ -148,8 +156,8 @@ public static void undo() {
return;
} else
imp.setProcessor(null, ipCopy);
if (whatToUndo==COMPOUND_FILTER_DONE)
undoOverlay(imp);
if (whatToUndo==COMPOUND_FILTER_DONE || whatToUndo==TYPE_CONVERSION)
undoOverlay(imp, true);
}
break;
case TRANSFORM:
Expand Down Expand Up @@ -184,18 +192,22 @@ public static void undo() {
IJ.beep();
return;
}
return; //don't reset
return; //don't reset; successive undo removes further rois
case OVERLAY:
undoOverlay(imp, false);
imp.draw();
break;
}
reset();
}

private static void undoOverlay(ImagePlus imp) {
if (overlayCopy!=null) {

/** Reverts the overlay to the saved version. */
private static void undoOverlay(ImagePlus imp, boolean onlyModifyOvly) {
if (overlayCopy!=null && imp.getID()==overlayImageID) {
Overlay overlay = imp.getOverlay();
if (overlay!=null) {
imp.setOverlay(overlayCopy);
overlayCopy = overlay.duplicate();
}
imp.setOverlay(overlayCopy);
if (overlay != null)
overlayCopy = overlay.duplicate(); //swap
}
}

Expand Down
39 changes: 32 additions & 7 deletions ij/gui/RoiProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ public class RoiProperties implements TextListener, WindowListener {
private TextField groupField, colorField;
private Label groupName;

/** Constructs a RoiProperties using the specified title for a given roi;
/** Constructs a RoiProperties using the specified title for a given image and roi;
* call showDialog for the actual dialog.
* Note that the title determines which fields will be shown in the dialog. */
public RoiProperties(String title, Roi roi) {
public RoiProperties(String title, ImagePlus imp, Roi roi) {
if (roi==null)
throw new IllegalArgumentException("ROI is null");
this.title = title;
this.imp = imp;
this.roi = roi;
showName = title.startsWith("Prop");
showListCoordinates = showName && title.endsWith(" ");
nProperties = showListCoordinates?roi.getPropertyCount():0;
Expand All @@ -48,12 +50,19 @@ public RoiProperties(String title, Roi roi) {
overlay = imp!=null?imp.getOverlay():null;
setPositions = roi.getPosition()!=0;
}
this.roi = roi;
}

/** Constructs a RoiProperties using the specified title for a given roi;
* call showDialog for the actual dialog.
* Note that the title determines which fields will be shown in the dialog. */

public RoiProperties(String title, Roi roi) {
this(title, WindowManager.getCurrentImage(), roi);
}

/** Displays the dialog box and returns 'false' if the user cancels it. */
public boolean showDialog() {
String name= roi.getName();
String name = roi.getName();
boolean isRange = name!=null && name.startsWith("range:");
String nameLabel = isRange?"Range:":"Name:";
if (isRange) name = name.substring(7);
Expand Down Expand Up @@ -99,7 +108,6 @@ else if (position.equals(""+PointRoi.POINTWISE_POSITION))
if (showName) {
gd.addStringField(nameLabel, name, 20);
String label = "Position:";
ImagePlus imp = WindowManager.getCurrentImage();
if (position.contains(",") || (imp!=null&&imp.isHyperStack()))
label = "Position (c,z,t):";
gd.addStringField(label, position, 20);
Expand Down Expand Up @@ -140,6 +148,9 @@ else if (position.equals(""+PointRoi.POINTWISE_POSITION))
gd.addStringField("Fill color:", fillc);
}
}
boolean askShowOnAllSlices = addToOverlay && imp!=null && imp.getNSlices()>1;
if (askShowOnAllSlices)
gd.addCheckbox("Show on all Slices", roi.getPosition()==0&&!roi.hasHyperStackPosition());
if (addToOverlay)
gd.addCheckbox("New overlay", false);
if (overlayOptions) {
Expand Down Expand Up @@ -211,8 +222,15 @@ else if (position.equals(""+PointRoi.POINTWISE_POSITION))
} else
fillc = gd.getNextString();
}
if (askShowOnAllSlices) {
boolean overlayOnAllSlices = gd.getNextBoolean();
if (overlayOnAllSlices)
roi.setPosition(0);
else if (roi.getPosition() == 0)
roi.setPosition(imp);
}
boolean applyToOverlay = false;
boolean newOverlay = addToOverlay?gd.getNextBoolean():false;
boolean newOverlay = addToOverlay ? gd.getNextBoolean() : false;
if (overlayOptions) {
setPositions = gd.getNextBoolean();
if (overlay!=null) {
Expand Down Expand Up @@ -267,12 +285,19 @@ else if (position.equals(""+PointRoi.POINTWISE_POSITION))
if (applyToOverlay) {
if (imp==null || overlay==null)
return true;
Undo.setup(Undo.OVERLAY, imp);
Roi[] rois = overlay.toArray();
for (int i=0; i<rois.length; i++) {
rois[i].setStrokeColor(strokeColor);
if (strokeColor != null)
rois[i].setStrokeColor(strokeColor);
if (strokeWidth2!=strokeWidth)
rois[i].setStrokeWidth((float)strokeWidth2);
rois[i].setFillColor(fillColor);
if (setPositions) {
if (rois[i].getPosition()==0 && !rois[i].hasHyperStackPosition())
rois[i].setPosition(imp);
} else
rois[i].setPosition(0);
}
imp.draw();
imp.getProcessor(); // needed for correct recordering
Expand Down
11 changes: 9 additions & 2 deletions ij/plugin/OverlayCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ void addSelection() {
gd.addCheckbox("Remove existing overlay", false);
gd.showDialog();
if (gd.wasCanceled()) return;
if (gd.getNextBoolean())
if (gd.getNextBoolean()) {
Undo.setup(Undo.OVERLAY, imp);
imp.setOverlay(null);
}
return;
}
if (roi==null) {
Expand All @@ -130,13 +132,17 @@ void addSelection() {
roi.setFillColor(defaultRoi.getFillColor());
}
setPosition(imp, roi);
boolean hasPosition = roi.getPosition()!=0 || roi.hasHyperStackPosition();
boolean points = roi instanceof PointRoi && ((PolygonRoi)roi).getNCoordinates()>1;
if (IJ.altKeyDown() || (IJ.macroRunning() && Macro.getOptions()!=null)) {
RoiProperties rp = new RoiProperties("Add to Overlay", roi);
if (!rp.showDialog()) return;
boolean hasPosition2 = roi.getPosition()!=0 || roi.hasHyperStackPosition();
defaultRoi.setStrokeColor(roi.getStrokeColor());
defaultRoi.setStrokeWidth(roi.getStrokeWidth());
defaultRoi.setFillColor(roi.getFillColor());
if (hasPosition2 != hasPosition)
defaultRoi.setPosition(hasPosition2 ? 1 : 0);
}
String name = roi.getName();
boolean newOverlay = name!=null && name.equals("new-overlay");
Expand Down Expand Up @@ -289,6 +295,7 @@ void remove() {
ImageCanvas ic = imp.getCanvas();
if (ic!=null)
ic.setShowAllList(null);
Undo.setup(Undo.OVERLAY, imp);
imp.setOverlay(null);
}
}
Expand Down Expand Up @@ -403,7 +410,7 @@ void options() {
boolean points = roi instanceof PointRoi && ((PolygonRoi)roi).getNCoordinates()>1;
if (points) roi.setStrokeColor(Color.red);
roi.setPosition(defaultRoi.getPosition());
RoiProperties rp = new RoiProperties("Overlay Options", roi);
RoiProperties rp = new RoiProperties("Overlay Options", imp, roi);
if (!rp.showDialog()) return;
defaultRoi = roi;
}
Expand Down
5 changes: 4 additions & 1 deletion ij/plugin/Resizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ else if (z1>1 && z1<stackSize)
newHeight = (int)Math.round(newWidth*(origHeight/origWidth));
}
ip.setInterpolationMethod(interpolationMethod);
Undo.setup(crop?Undo.TRANSFORM:Undo.TYPE_CONVERSION, imp);
if (stackSize==1)
Undo.setup(crop?Undo.TRANSFORM:Undo.TYPE_CONVERSION, imp);
if (imp.getOverlay() != null)
Undo.saveOverlay(imp);

if (roi!=null || newWidth!=origWidth || newHeight!=origHeight) {
try {
Expand Down
12 changes: 8 additions & 4 deletions ij/plugin/Selection.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ else if (arg.equals("toarea"))
else if (arg.equals("toline"))
areaToLine(imp);
else if (arg.equals("properties"))
{setProperties("Properties ", imp.getRoi()); imp.draw();}
{setProperties("Properties ", imp); imp.draw();}
else if (arg.equals("band"))
makeBand(imp);
else if (arg.equals("tobox"))
Expand Down Expand Up @@ -800,8 +800,12 @@ void addToRoiManager(ImagePlus imp) {
rm.allowRecording(false);
IJ.setKeyUp(IJ.ALL_KEYS);
}

boolean setProperties(String title, Roi roi) {

/** Implements the Edit>Selection>Properties command.
* With the alt key down and a multipoint selection, shows the point counts instead. */
boolean setProperties(String title, ImagePlus imp) {
if (imp == null) return false; //should never happen (called only from 'run', where imp!=null)
Roi roi = imp.getRoi();
if ((roi instanceof PointRoi) && Toolbar.getMultiPointMode() && IJ.altKeyDown()) {
((PointRoi)roi).displayCounts();
return true;
Expand All @@ -820,7 +824,7 @@ boolean setProperties(String title, Roi roi) {
Color color = roi.getStrokeColor();
Color fillColor = roi.getFillColor();
int width = (int)roi.getStrokeWidth();
RoiProperties rp = new RoiProperties(title, roi);
RoiProperties rp = new RoiProperties(title, imp, roi);
boolean ok = rp.showDialog();
if (Recorder.record) {
boolean groupChanged = false;
Expand Down
31 changes: 14 additions & 17 deletions ij/plugin/frame/ContrastAdjuster.java
Original file line number Diff line number Diff line change
Expand Up @@ -435,25 +435,24 @@ void updateLabels(ImagePlus imp) {
max = cal.getCValue((int)max);
realValue = true;
}
digits = realValue?4:0;
if (realValue) {
double s = min<0||max<0?0.1:1.0;
double amin = Math.abs(min);
double amax = Math.abs(max);
if (amin>99.0*s||amax>99.0*s) digits = 3;
if (amin>999.0*s||amax>999.0*s) digits = 2;
if (amin>9999.0*s||amax>9999.0*s) digits = 1;
if (amin>99999.0*s||amax>99999.0*s) digits = 0;
if (amin>9999999.0*s||amax>9999999.0*s) digits = -2;
if ((amin>0&&amin<0.001)||(amax>0&&amax<0.001)) digits = -2;
}
if (windowLevel) {
digits = realValue?3:0;
double window = max-min;
double level = min+(window)/2.0;
windowLabel.setText(ResultsTable.d2s(window, digits));
levelLabel.setText(ResultsTable.d2s(level, digits));
} else {
digits = realValue?4:0;
if (realValue) {
double s = min<0||max<0?0.1:1.0;
double amin = Math.abs(min);
double amax = Math.abs(max);
if (amin>99.0*s||amax>99.0*s) digits = 3;
if (amin>999.0*s||amax>999.0*s) digits = 2;
if (amin>9999.0*s||amax>9999.0*s) digits = 1;
if (amin>99999.0*s||amax>99999.0*s) digits = 0;
if (amin>9999999.0*s||amax>9999999.0*s) digits = -2;
if ((amin>0&&amin<0.001)||(amax>0&&amax<0.001)) digits = -2;
}
String minString = IJ.d2s(min, min==0.0?0:digits) + blankLabel8;
minLabel.setText(minString.substring(0,blankLabel8.length()));
String maxString = blankLabel8 + IJ.d2s(max, digits);
Expand Down Expand Up @@ -868,7 +867,6 @@ void setMinAndMax(ImagePlus imp, ImageProcessor ip) {
min = imp.getDisplayRangeMin();
max = imp.getDisplayRangeMax();
Calibration cal = imp.getCalibration();
//int digits = (ip instanceof FloatProcessor)||cal.calibrated()?2:0;
double minValue = cal.getCValue(min);
double maxValue = cal.getCValue(max);
int channels = imp.getNChannels();
Expand Down Expand Up @@ -1024,15 +1022,14 @@ void setWindowLevel(ImagePlus imp, ImageProcessor ip) {
min = imp.getDisplayRangeMin();
max = imp.getDisplayRangeMax();
Calibration cal = imp.getCalibration();
int digits = (ip instanceof FloatProcessor)||cal.calibrated()?2:0;
double minValue = cal.getCValue(min);
double maxValue = cal.getCValue(max);
//IJ.log("setWindowLevel: "+min+" "+max);
double windowValue = maxValue - minValue;
double levelValue = minValue + windowValue/2.0;
GenericDialog gd = new GenericDialog("Set W&L");
gd.addNumericField("Window Center (Level): ", levelValue, digits);
gd.addNumericField("Window Width: ", windowValue, digits);
gd.addNumericField("Window Center (Level): ", levelValue, digits, 9, "");
gd.addNumericField("Window Width: ", windowValue, digits, 9, "");
gd.addCheckbox("Propagate to all open images", false);
gd.showDialog();
if (gd.wasCanceled())
Expand Down
Loading

0 comments on commit 10e9086

Please sign in to comment.