Skip to content
Permalink
Browse files

2019.09.10 (1.52q47; Lines to ShapeRois)

  • Loading branch information...
rasband committed Sep 11, 2019
1 parent bf9a36d commit cd3dd6e22d8c09885436ca6d44d5e86ce13e058c
@@ -937,6 +937,14 @@ public static String pad(int n, int digits) {
return str;
}

/** Pad 's' with leading zeros to the specified number of digits. */
public static String pad(String s, int digits) {
String str = ""+s;
while (str.length()<digits)
str = "0"+str;
return str;
}

/** Adds the specified class to a Vector to keep it from being garbage
collected, which would cause the classes static fields to be reset.
Probably not needed with Java 1.2 or later. */
@@ -78,7 +78,7 @@ Runs a macro or script (JavaScript, BeanShell or Python) in

/** Plugins should call IJ.getVersion() or IJ.getFullVersion() to get the version string. */
public static final String VERSION = "1.52q";
public static final String BUILD = "44";
public static final String BUILD = ""; //47
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);
@@ -6,7 +6,6 @@
import ij.plugin.filter.Analyzer;
import ij.plugin.filter.ThresholdToSelection;
import ij.plugin.RectToolOptions;
import ij.plugin.Selection;
import ij.macro.Interpreter;
import ij.io.RoiDecoder;
import java.awt.*;
@@ -610,15 +609,11 @@ protected FloatPolygon getInterpolatedPolygon(FloatPolygon p, double interval, b
* @see #iterator()
*/
public Point[] getContainedPoints() {
if (isLine()) {
FloatPolygon p = getInterpolatedPolygon();
Point[] points = new Point[p.npoints];
for (int i=0; i<p.npoints; i++)
points[i] = new Point((int)Math.round(p.xpoints[i]),(int)Math.round(p.ypoints[i]));
return points;
}
ImageProcessor mask = getMask();
Rectangle bounds = getBounds();
Roi roi = this;
if (isLine())
roi = toArea();
ImageProcessor mask = roi.getMask();
Rectangle bounds = roi.getBounds();
ArrayList points = new ArrayList();
for (int y=0; y<bounds.height; y++) {
for (int x=0; x<bounds.width; x++) {
@@ -639,7 +634,7 @@ public FloatPolygon getContainedFloatPoints() {
if (getStrokeWidth()<=1)
return roi2.getInterpolatedPolygon();
else
roi2 = Selection.lineToArea(this);
roi2 = toArea();
}
ImageProcessor mask = roi2.getMask();
Rectangle bounds = roi2.getBounds();
@@ -2254,7 +2249,59 @@ public int size() {
yC /= lSum;
return new double[]{xC, yC};
}


/** Converts this selection into an area selection. */
public Roi toArea() {
if (!isLine())
return this;
Roi roi = (Roi)this.clone();
Roi roi2 = null;
if (roi.getType()==Roi.LINE) {
double width = roi.getStrokeWidth();
if (width<=1.0)
roi.setStrokeWidth(1.0000001);
FloatPolygon p = roi.getFloatPolygon();
roi.setStrokeWidth(width);
roi2 = new PolygonRoi(p, Roi.POLYGON);
roi2.setDrawOffset(roi.getDrawOffset());
} else {
int lwidth = (int)roi.getStrokeWidth();
if (lwidth<1)
lwidth = 1;
Rectangle bounds = roi.getBounds();
int width = bounds.width + lwidth*2;
int height = bounds.height + lwidth*2;
ImageProcessor ip2 = new ByteProcessor(width, height);
roi.setLocation(lwidth, lwidth);
ip2.setColor(255);
roi.drawPixels(ip2);
ip2.setThreshold(255, 255, ImageProcessor.NO_LUT_UPDATE);
ThresholdToSelection tts = new ThresholdToSelection();
roi2 = tts.convert(ip2);
if (roi2==null)
return roi;
if (bounds.x==0&&bounds.y==0)
roi2.setLocation(0, 0);
else
roi2.setLocation(bounds.x-lwidth/2, bounds.y-lwidth/2);
}
transferProperties(roi, roi2);
roi2.setStrokeWidth(0);
Color c = roi2.getStrokeColor();
if (c!=null) // remove any transparency
roi2.setStrokeColor(new Color(c.getRed(),c.getGreen(),c.getBlue()));
return roi2;
}

private static void transferProperties(Roi roi1, Roi roi2) {
if (roi1==null || roi2==null)
return;
roi2.setStrokeColor(roi1.getStrokeColor());
if (roi1.getStroke()!=null)
roi2.setStroke(roi1.getStroke());
roi2.setDrawOffset(roi1.getDrawOffset());
}

/** Returns a hashcode for this Roi that typically changes
if it is moved, even though it is still the same object. */
public int getHashCode() {
@@ -2320,7 +2367,7 @@ public static void removeRoiListener(RoiListener listener) {

RoiPointsIteratorMask() {
if (isLine()) {
Roi roi2 = Selection.lineToArea(Roi.this);
Roi roi2 = Roi.this.toArea();
mask = roi2.getMask();
xbase = roi2.x;
ybase = roi2.y;
@@ -139,11 +139,9 @@ public ShapeRoi(float[] shapeArray) {
x = r.x;
y = r.y;
width = r.width;
height = r.height;

height = r.height;
state = NORMAL;
oldX=x; oldY=y; oldWidth=width; oldHeight=height;

oldX=x; oldY=y; oldWidth=width; oldHeight=height;
AffineTransform at = new AffineTransform();
at.translate(-x, -y);
shape = new GeneralPath(at.createTransformedShape(shape));
@@ -267,6 +265,8 @@ ShapeRoi unaryOp(ShapeRoi sr, int op) {
*
*/
private Shape roiToShape(Roi roi) {
if (roi.isLine())
roi = roi.toArea();
Shape shape = null;
Rectangle r = roi.getBounds();
boolean closeShape = true;
@@ -6189,7 +6189,7 @@ private String ijCall() {
interp.error("Function name expected: ");
String name = interp.tokenString;
if (name.equals("pad"))
return IJ.pad((int)getFirstArg(), (int)getLastArg());
return pad();
else if (name.equals("deleteRows"))
IJ.deleteRows((int)getFirstArg(), (int)getLastArg());
else if (name.equals("log"))
@@ -6212,6 +6212,21 @@ else if (name.equals("getFullVersion"))
interp.error("Unrecognized IJ function name");
return null;
}

private String pad() {
int intArg = 0;
String stringArg = null;
interp.getLeftParen();
if (isStringArg())
stringArg = getString();
else
intArg = (int)interp.getExpression();
int digits = (int)getLastArg();
if (stringArg!=null)
return IJ.pad(stringArg, digits);
else
return IJ.pad(intArg, digits);
}

private void renameResults() {
String arg1 = getFirstString();
@@ -637,43 +637,7 @@ private void lineToArea(ImagePlus imp) {

/** Converts a line selection into an area selection. */
public static Roi lineToArea(Roi roi) {
Roi roi2 = null;
if (roi.getType()==Roi.LINE) {
double width = roi.getStrokeWidth();
if (width<=1.0)
roi.setStrokeWidth(1.0000001);
FloatPolygon p = roi.getFloatPolygon();
roi.setStrokeWidth(width);
roi2 = new PolygonRoi(p, Roi.POLYGON);
roi2.setDrawOffset(roi.getDrawOffset());
} else {
roi = (Roi)roi.clone();
int lwidth = (int)roi.getStrokeWidth();
if (lwidth<1)
lwidth = 1;
Rectangle bounds = roi.getBounds();
int width = bounds.width + lwidth*2;
int height = bounds.height + lwidth*2;
ImageProcessor ip2 = new ByteProcessor(width, height);
roi.setLocation(lwidth, lwidth);
ip2.setColor(255);
roi.drawPixels(ip2);
ip2.setThreshold(255, 255, ImageProcessor.NO_LUT_UPDATE);
ThresholdToSelection tts = new ThresholdToSelection();
roi2 = tts.convert(ip2);
if (roi2==null)
return roi;
if (bounds.x==0&&bounds.y==0)
roi2.setLocation(0, 0);
else
roi2.setLocation(bounds.x-lwidth/2, bounds.y-lwidth/2);
}
transferProperties(roi, roi2);
roi2.setStrokeWidth(0);
Color c = roi2.getStrokeColor();
if (c!=null) // remove any transparency
roi2.setStrokeColor(new Color(c.getRed(),c.getGreen(),c.getBlue()));
return roi2;
return roi.toArea();
}

void areaToLine(ImagePlus imp) {
@@ -1473,20 +1473,15 @@ private int countPointRois(Roi[] rois) {
private void combineRois(ImagePlus imp, Roi[] rois) {
IJ.resetEscape();
ShapeRoi s1=null, s2=null;
ImageProcessor ip = null;
for (int i=0; i<rois.length; i++) {
IJ.showProgress(i, rois.length-1);
if (IJ.escapePressed()) {
IJ.showProgress(1.0);
return;
}
Roi roi = rois[i];
if (!roi.isArea() && roi.getType() != Roi.POINT) {
if (ip==null)
ip = new ByteProcessor(imp.getWidth(), imp.getHeight());
roi = convertLineToPolygon(roi, ip);
if (roi==null) continue;
}
if (!roi.isArea() && roi.getType() != Roi.POINT)
roi = roi.toArea();
if (s1==null) {
if (roi instanceof ShapeRoi)
s1 = (ShapeRoi)roi;
@@ -1506,22 +1501,6 @@ private void combineRois(ImagePlus imp, Roi[] rois) {
imp.setRoi(s1.trySimplify());
}

Roi convertLineToPolygon(Roi roi, ImageProcessor ip) {
if (roi==null) return null;
ip.resetRoi();
ip.setColor(0);
ip.fill();
ip.setColor(255);
if (roi.getType()==Roi.LINE && roi.getStrokeWidth()>1)
ip.fillPolygon(roi.getPolygon());
else
roi.drawPixels(ip);
//new ImagePlus("ip", ip.duplicate()).show();
ip.setThreshold(255, 255, ImageProcessor.NO_LUT_UPDATE);
ThresholdToSelection tts = new ThresholdToSelection();
return tts.convert(ip);
}

void combinePoints(ImagePlus imp, Roi[] rois) {
int n = rois.length;
FloatPolygon fp = new FloatPolygon();
@@ -1533,7 +1512,7 @@ void combinePoints(ImagePlus imp, Roi[] rois) {
imp.setRoi(new PointRoi(fp));
}

/** Intersection of area rois or PointRois.
/** calculates the intersection of area, line and point selections.
* If there is one PointRoi in the list of selected Rois, the points inside all selected area rois are kept.
* If more than one PointRoi is selected, the PointRois get converted to area rois with each pixel containing
* at least one point selected. */
@@ -1549,10 +1528,10 @@ void and() {
ShapeRoi s1=null;
PointRoi pointRoi = null;
for (Roi roi : rois) {
if (roi==null || !(roi.isArea() || roi.getType() == Roi.POINT))
if (roi==null)
continue;
if (s1==null) {
if (nPointRois == 1 && roi.getType() == Roi.POINT) {
if (nPointRois==1 && roi.getType() == Roi.POINT) {
pointRoi = (PointRoi)roi;
continue; //PointRoi will be handled at the end
}
@@ -1562,7 +1541,7 @@ void and() {
s1 = new ShapeRoi(roi);
if (s1==null) continue;
} else {
if (nPointRois == 1 && roi.getType() == Roi.POINT) {
if (nPointRois==1 && roi.getType()==Roi.POINT) {
pointRoi = (PointRoi)roi;
continue; //PointRoi will be handled at the end
}
@@ -1576,9 +1555,12 @@ void and() {
}
}
if (s1==null) return;
if (pointRoi != null) imp.setRoi(pointRoi.containedPoints(s1));
else imp.setRoi(s1.trySimplify());
if (record()) Recorder.record("roiManager", "AND");
if (pointRoi!=null)
imp.setRoi(pointRoi.containedPoints(s1));
else
imp.setRoi(s1.trySimplify());
if (record())
Recorder.record("roiManager", "AND");
}

void xor() {
@@ -1594,7 +1576,7 @@ void xor() {
ShapeRoi s1=null, s2=null;
for (int i=0; i<indexes.length; i++) {
Roi roi = (Roi)rois.get(indexes[i]);
if (roi==null || !(roi.isArea() || roi.getType() == Roi.POINT))
if (roi==null)
continue;
if (s1==null) {
if (roi instanceof ShapeRoi)
@@ -561,8 +561,7 @@ public void actionPerformed(ActionEvent e) {
v.addElement(I);
}
addWindows(v);
}
else if(bpressed==bUnsyncAll) {
} else if(bpressed==bUnsyncAll) {
removeAllWindows();
}
} else if (wList != null && source == wList) {
@@ -5,7 +5,7 @@
</head>
<body>

<li> <u>1.52q44 26 August 2019</u>
<li> <u>1.52q47 10 September 2019</u>
<ul>
<li> Thanks to Michael Schmid, added the "Non-blocking filter dialogs"
option to <i>Edit&gt;Options&gt;Misc</i>. The Convolve,
@@ -29,6 +29,8 @@
plot window commands also now use labels.
<li> Thanks to Jerome Mutterer, added the getValue("Length")
macro function.
<li> Thanks to Jerome Mutterer, added the IJ.pad(string,digits)
macro function and method.
<li> Thanks to Michael Schmid, the ImagePlus lock() and unlock()
methods now support multiple lock/unlock operations by the
same thread.
@@ -68,17 +70,21 @@
<li> Thanks to Norbert Vischer, fixed a bug that caused
the getPixel(x,y) macro function to not return raw pixel values
when x or y were real numbers.
<li> Thanks to Hyung-song Nam and Curtis Rueden, fixed a bug
that caused the Channels tool on macOS to become unresponsive.
<li> Thanks to Florian Jug, fixed a bug that caused the "Auto"
button in the "B&C" tool to not have focus on macOS.
<li> Thanks to 'mountain_man', fixed a bug that caused
line selections to not be correctly converted to ShapeRois.
<li> Thanks to Jeremy Adler, fixed a regression that caused the
the makeSelection(10, xpoints, ypoints) macro function to
throw an exception.
<li> Thanks to Dan McDonald, fixed a regression that caused the
Raw File Opener to throw an exception.
<li> Fixed a 1.52a regression that caused tables created by
the gel analyzer to not have row numbers.
<li> Thanks to Hyung-song Nam and Curtis Rueden, fixed a
1.52o regression that caused the Channels tool on macOS
to become unresponsive.
<li> Thanks to Florian Jug, fixed a 1.52o regression that
caused the "Auto" button in the "B&C" tool to not have
focus on macOS.
</ul>

<li> <u>1.52p 22 June 2019</u>

0 comments on commit cd3dd6e

Please sign in to comment.
You can’t perform that action at this time.