File: Rotator.java

package info (click to toggle)
imagej 1.51i%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 5,244 kB
  • ctags: 13,220
  • sloc: java: 113,144; sh: 285; xml: 50; makefile: 8
file content (157 lines) | stat: -rw-r--r-- 4,946 bytes parent folder | download
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package ij.plugin.filter;
import ij.*;
import ij.gui.*;
import ij.process.*;
import java.awt.*;
import java.awt.geom.*;


/** This plugin implements the Image/Rotate/Arbitrarily command. */
public class Rotator implements ExtendedPlugInFilter, DialogListener {
	private int flags = DOES_ALL|SUPPORTS_MASKING|PARALLELIZE_STACKS;
	private static double angle = 15.0;
	private static boolean fillWithBackground;
	private static boolean enlarge;
	private static int gridLines = 1;
	private ImagePlus imp;
	private int bitDepth;
	private boolean canEnlarge;
	private boolean isEnlarged;
	private GenericDialog gd;
	private PlugInFilterRunner pfr;
	private String[] methods = ImageProcessor.getInterpolationMethods();
	private static int interpolationMethod = ImageProcessor.BILINEAR;

	public int setup(String arg, ImagePlus imp) {
		this.imp = imp;
		if (imp!=null) {
			bitDepth = imp.getBitDepth();
			Roi roi = imp.getRoi();
			Rectangle r = roi!=null?roi.getBounds():null;
			canEnlarge = r==null || (r.x==0&&r.y==0&&r.width==imp.getWidth()&&r.height==imp.getHeight());
		}
		return flags;
	}

	public void run(ImageProcessor ip) {
		if(enlarge && gd.wasOKed()) synchronized(this) {
			if (!isEnlarged) {
				enlargeCanvas();
				isEnlarged=true;
			}
		}
		if (isEnlarged) {	//enlarging may have made the ImageProcessor invalid, also for the parallel threads
			int slice = pfr.getSliceNumber();
			if (imp.getStackSize()==1)
				ip = imp.getProcessor();
			else
				ip = imp.getStack().getProcessor(slice);
		}
		ip.setInterpolationMethod(interpolationMethod);
		if (fillWithBackground) {
			Color bgc = Toolbar.getBackgroundColor();
			if (bitDepth==8)
				ip.setBackgroundValue(ip.getBestIndex(bgc));
			else if (bitDepth==24)
				ip.setBackgroundValue(bgc.getRGB());
		} else
			ip.setBackgroundValue(0);
		ip.rotate(angle);
		if (!gd.wasOKed())
			drawGridLines(gridLines);
		if (isEnlarged && imp.getStackSize()==1) {
			imp.changes = true;
			imp.updateAndDraw();
			Undo.setup(Undo.COMPOUND_FILTER_DONE, imp);
		}
	}

	void enlargeCanvas() {
		imp.unlock();
		if (imp.getStackSize()==1)
			Undo.setup(Undo.COMPOUND_FILTER, imp);
		IJ.run("Select All");
		IJ.run("Rotate...", "angle="+angle);
		Roi roi = imp.getRoi();
		Rectangle r = roi.getBounds();
		if (r.width<imp.getWidth()) r.width = imp.getWidth();
		if (r.height<imp.getHeight()) r.height = imp.getHeight();
		IJ.showStatus("Rotate: Enlarging...");
		IJ.run("Canvas Size...", "width="+r.width+" height="+r.height+" position=Center "+(fillWithBackground?"":"zero"));
		IJ.showStatus("Rotating...");
	}

	void drawGridLines(int lines) {
		ImageCanvas ic = imp.getCanvas();
		if (ic==null) return;
		if (lines==0) {ic.setDisplayList(null); return;}
		GeneralPath path = new GeneralPath();
		float width = imp.getWidth();
		float height = imp.getHeight();
		float xinc = width/lines;
		float yinc = height/lines;
		float xstart = xinc/2f;
		float ystart = yinc/2f;
		for (int i=0; i<lines; i++) {
			path.moveTo(xstart+xinc*i, 0f);
			path.lineTo(xstart+xinc*i, height);
			path.moveTo(0f, ystart+yinc*i);
			path.lineTo(width, ystart+yinc*i);
		}
		ic.setDisplayList(path, null, null);
	}
	
	public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {
		this.pfr = pfr;
		String macroOptions = Macro.getOptions();
		if (macroOptions!=null) {
			if (macroOptions.indexOf(" interpolate")!=-1)
				macroOptions.replaceAll(" interpolate", " interpolation=Bilinear");
			else if (macroOptions.indexOf(" interpolation=")==-1)
				macroOptions = macroOptions+" interpolation=None";
			Macro.setOptions(macroOptions);
		}
		gd = new GenericDialog("Rotate");
		gd.addNumericField("Angle (degrees):", angle, (int)angle==angle?1:2);
		gd.addNumericField("Grid Lines:", gridLines, 0);
		gd.addChoice("Interpolation:", methods, methods[interpolationMethod]);
		if (bitDepth==8 || bitDepth==24)
			gd.addCheckbox("Fill with Background Color", fillWithBackground);
		if (canEnlarge)
			gd.addCheckbox("Enlarge Image to Fit Result", enlarge);
		else
			enlarge = false;
		gd.addPreviewCheckbox(pfr);
		gd.addDialogListener(this);
		gd.showDialog();
		drawGridLines(0);
		if (gd.wasCanceled())
			return DONE;
		if (!enlarge)
			flags |= KEEP_PREVIEW;		// standard filter without enlarge
		else if (imp.getStackSize()==1)
			flags |= NO_CHANGES;			// undoable as a "compound filter"
		return IJ.setupDialog(imp, flags);
	}
	
	public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
		angle = gd.getNextNumber();
		//only check for invalid input to "angle", don't care about gridLines
		if (gd.invalidNumber()) {
			if (gd.wasOKed()) IJ.error("Angle is invalid.");
			return false;
		}
		gridLines = (int)gd.getNextNumber();
		interpolationMethod = gd.getNextChoiceIndex();
		if (bitDepth==8 || bitDepth==24)
			fillWithBackground = gd.getNextBoolean();
		if (canEnlarge)
			enlarge = gd.getNextBoolean();
		return true;
	}

	public void setNPasses(int nPasses) {
	}

}