File: RoiScaler.java

package info (click to toggle)
imagej 1.52j-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 5,604 kB
  • sloc: java: 120,017; sh: 279; xml: 161; makefile: 6
file content (121 lines) | stat: -rw-r--r-- 3,593 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import java.awt.geom.*;

/** This plugin implements the Edit/Selection/Scale command. */
public class RoiScaler implements PlugIn {
	private static double defaultXScale = 1.5;
	private static double defaultYScale = 1.5;
	private double xscale;
	private double yscale;
	private boolean centered;

	public void run(String arg) {
		ImagePlus imp = IJ.getImage();
		Roi roi = imp.getRoi();
		if (roi==null) {
			IJ.error("Scale", "This command requires a selection");
			return;
		}
		if (!showDialog())
			return;
		if (!IJ.macroRunning()) {
			defaultXScale = xscale;
			defaultYScale = yscale;
		}
		//if (roi instanceof ImageRoi) {
		//	((ImageRoi)roi).rotate(angle);
		//	imp.draw();
		//	return;
		//}
		Roi roi2 = scale(roi, xscale, yscale, centered);
		if (roi2==null)
			return;
		Undo.setup(Undo.ROI, imp);
		roi = (Roi)roi.clone();
		imp.setRoi(roi2);
		Roi.previousRoi = roi;
	}
	
	public boolean showDialog() {
		GenericDialog gd = new GenericDialog("Scale Selection");
		gd.addNumericField("X scale factor:", defaultXScale, 2, 3, "");
		gd.addNumericField("Y scale factor:", defaultYScale, 2, 3, "");
		gd.addCheckbox("Centered", false);
		gd.showDialog();
		if (gd.wasCanceled())
			return false;
		xscale = gd.getNextNumber();
		yscale = gd.getNextNumber();
		centered = gd.getNextBoolean();
		return true;
	}
	
	public static Roi scale(Roi roi, double xscale, double yscale, boolean centered) {
		if (roi instanceof ShapeRoi)
			return scaleShape((ShapeRoi)roi, xscale, yscale, centered);
		FloatPolygon poly = roi.getFloatPolygon();
		int type = roi.getType();
		if (type==Roi.LINE) {
			Line line = (Line)roi;
			double x1=line.x1d;
			double y1=line.y1d;
			double x2=line.x2d;
			double y2=line.y2d;
			poly = new FloatPolygon();
			poly.addPoint(x1, y1);
			poly.addPoint(x2, y2);
		}
		Rectangle r = roi.getBounds();
		double xbase = r.x - (r.width*xscale-r.width)/2.0;
		double ybase = r.y - (r.height*yscale-r.height)/2.0;
		for (int i=0; i<poly.npoints; i++) {
			if (centered) {
				poly.xpoints[i] = (float)((poly.xpoints[i]-r.x)*xscale + xbase);
				poly.ypoints[i] = (float)((poly.ypoints[i]-r.y)*yscale + ybase);
			} else {
				poly.xpoints[i] = (float)(poly.xpoints[i]*xscale);
				poly.ypoints[i] = (float)(poly.ypoints[i]*yscale);
			}
		}
		Roi roi2 = null;
		if (type==Roi.LINE)
			roi2 = new Line(poly.xpoints[0], poly.ypoints[0], poly.xpoints[1], poly.ypoints[1]);
		else if (type==Roi.POINT)
			roi2 = new PointRoi(poly.xpoints, poly.ypoints,poly.npoints);
		else {
			if (type==Roi.RECTANGLE)
				type = Roi.POLYGON;
			if (type==Roi.RECTANGLE && poly.npoints>4) // rounded rectangle
				type = Roi.FREEROI;
			if (type==Roi.OVAL||type==Roi.TRACED_ROI)
				type = Roi.FREEROI;
			roi2 = new PolygonRoi(poly.xpoints, poly.ypoints,poly.npoints, type);
		}
		roi2.setStrokeColor(roi.getStrokeColor());
		if (roi.getStroke()!=null)
			roi2.setStroke(roi.getStroke());
		return roi2;
	}
	
	private static Roi scaleShape(ShapeRoi roi, double xscale, double yscale, boolean centered) {
		Rectangle r = roi.getBounds();
		Shape shape = roi.getShape();
		AffineTransform at = new AffineTransform();
		at.scale(xscale, yscale);
		if (!centered)
			at.translate(r.x, r.y);
		Shape shape2 = at.createTransformedShape(shape);
		Roi roi2 = new ShapeRoi(shape2);
		if (centered) {
			int xbase = (int)(centered?r.x-(r.width*xscale-r.width)/2.0:r.x);
			int ybase = (int)(centered?r.y-(r.height*yscale-r.height)/2.0:r.y);
			roi2.setLocation(xbase, ybase);
		}
		return roi2;
	}
	
}