/Users/lyon/j4p/src/ip/raul/MorphLog.java
|
1 package ip.raul;
2
3 import ip.gui.dialog.ExpandoLog;
4 import ip.gui.frames.AnimateFrame;
5 import ip.gui.frames.XformFrame;
6
7 import java.awt.*;
8 import java.awt.event.ActionEvent;
9 import java.awt.event.ActionListener;
10
11 public class MorphLog extends XformFrame
12 implements ActionListener {
13
14 MenuBar mb = new MenuBar();
15 Menu SettingsMenu = new Menu("Settings");
16
17 MenuItem props_mi = addMenuItem(SettingsMenu, "[p]roperties");
18 MenuItem default_mi = addMenuItem(SettingsMenu, "[d]efault images");
19 MenuItem morph_mi = addMenuItem(SettingsMenu, "[m]orph");
20
21 short rm[][] = new short[0][0];
22 short gm[][] = new short[0][0];
23 short bm[][] = new short[0][0];
24
25 short rc[][] = new short[0][0];
26 short gc[][] = new short[0][0];
27 short bc[][] = new short[0][0];
28 Image img = null;
29 Polygon p = new Polygon();
30 boolean doMorph = false;
31 GridImage SourceImage = null;
32 GridImage StopImage = null;
33 int w = 128;
34 int h = 128;
35 int nPoints = 25;
36 int gridX = 5;
37 int gridY = 5;
38 int NumberOfFrames = 50;
39 boolean busy = false;
40 String prompts[] = {
41 "Grid X Elements=",
42 "Grid Y Elements=",
43 "Number Of Frames="};
44 String defaults[] = {
45 "" + gridX,
46 "" + gridY,
47 "" + NumberOfFrames};
48 ip.gui.dialog.ExpandoLog el = null;
49
50
51 public void actionPerformed(ActionEvent e) {
52
53 if (el != null) {
54 String s[] = el.getUserInput();
55 gridX = Integer.parseInt(s[0]);
56 gridY = Integer.parseInt(s[1]);
57 NumberOfFrames = Integer.parseInt(s[2]);
58 SourceImage.setGrid(gridX, gridY);
59 StopImage.setGrid(gridX, gridY);
60 el = null;
61 }
62
63 if (match(e, morph_mi)) {
64 Morph();
65 return;
66 }
67
68 if (match(e, props_mi)) {
69 Properties();
70 return;
71 }
72
73 if (match(e, default_mi)) {
74 default1();
75 return;
76 }
77
78 super.actionPerformed(e);
79 }
80
81 MorphLog(String title) {
82 super(title);
83 init();
84 mb.add(SettingsMenu);
85 setMenuBar(mb);
86 SourceImage = new GridImage("Source Image", Color.red);
87 StopImage = new GridImage("Stop Image", Color.green);
88 repaint();
89 }
90
91 private void init() {
92 }
93
94 public void Morph() {
95 int maxW = 0;
96 int maxH = 0;
97 int sourceX, sourceY;
98 int stopX, stopY;
99 AnimateFrame af = new AnimateFrame();
100 double k = 0;
101 if (getImageWidth() > maxW) maxW = getImageWidth();
102 if (getImageHeight() > maxH) maxH = getImageHeight();
103 if (getImageWidth() > maxW) maxW = getImageWidth();
104 if (getImageHeight() > maxH) maxH = getImageHeight();
105 setSize(maxW, maxH);
106 repaint();
107 rm = new short[maxW][maxH];
108 gm = new short[maxW][maxH];
109 bm = new short[maxW][maxH];
110 rc = new short[maxW][maxH];
111 gc = new short[maxW][maxH];
112 bc = new short[maxW][maxH];
113 setImageHeight(maxH);
114 setImageWidth(maxW);
115 short[][] r = rm;
116 shortImageBean.setR(r);
117 setG(gm);
118 setB(bm);
119 short2Image();
120 img = getImage();
121
122 nPoints = (gridX + 1) * (gridY + 1);
123 p = new Polygon();
124 for (int j = 0; j < nPoints; j++) {
125 p.addPoint(SourceImage.p.xpoints[j],
126 SourceImage.p.ypoints[j]);
127 }
128
129 String files = "seq";//getFileNames();
130 busy = true;
131 for (int i = 0; i < NumberOfFrames; i++) {
132 k = (double) ((double) i / (double) (NumberOfFrames - 1));
133 for (int j = 0; j < nPoints; j++) {
134 sourceX = SourceImage.p.xpoints[j];
135 sourceY = SourceImage.p.ypoints[j];
136 stopX = StopImage.p.xpoints[j];
137 stopY = StopImage.p.ypoints[j];
138 p.xpoints[j] = (int) linearY(sourceX, stopX, k);
139 p.ypoints[j] = (int) linearY(sourceY, stopY, k);
140 }
141 applyBilinearMorph(k);
142 short[][] r1 = rm;
143 shortImageBean.setR(r1);
144 setG(gm);
145 setB(bm);
146 medianCut(256);
147
148 img = getImage();
149 af.addImage(img);
150 System.out.println((NumberOfFrames - i - 1) + " steps left...");
151
152 int outFileNumber = i;
153 // String outFileName = "d:\\cadgfx\\pics\\morph\\"+outFileNumber+".GIF";
154 // System.out.println("writing:"+outFileName);
155 // saveAsGif(outFileName);
156
157 }
158 af.saveImages();
159 af.setSize(getImageWidth(), getImageHeight());
160 af.setVisible(true);
161 }
162
163
164 public void applyBilinearMorph(double k) {
165 Point s0,s1,s2,s3,m0,m1,m2,m3,d0,d1,d2,d3;
166 for (int i = 0; i < gridY; i++)
167 for (int j = 0; j < gridX; j++) {
168 s0 = new Point(SourceImage.p.xpoints[j + i * (gridX + 1)], SourceImage.p.ypoints[j + i * (gridX + 1)]);
169 s1 = new Point(SourceImage.p.xpoints[j + 1 + i * (gridX + 1)], SourceImage.p.ypoints[j + 1 + i * (gridX + 1)]);
170 s2 = new Point(SourceImage.p.xpoints[j + 1 + (i + 1) * (gridX + 1)], SourceImage.p.ypoints[j + 1 + (i + 1) * (gridX + 1)]);
171 s3 = new Point(SourceImage.p.xpoints[j + (i + 1) * (gridX + 1)], SourceImage.p.ypoints[j + (i + 1) * (gridX + 1)]);
172 m0 = new Point(p.xpoints[j + i * (gridX + 1)], p.ypoints[j + i * (gridX + 1)]);
173 m1 = new Point(p.xpoints[j + 1 + i * (gridX + 1)], p.ypoints[j + 1 + i * (gridX + 1)]);
174 m2 = new Point(p.xpoints[j + 1 + (i + 1) * (gridX + 1)], p.ypoints[j + 1 + (i + 1) * (gridX + 1)]);
175 m3 = new Point(p.xpoints[j + (i + 1) * (gridX + 1)], p.ypoints[j + (i + 1) * (gridX + 1)]);
176 d0 = new Point(StopImage.p.xpoints[j + i * (gridX + 1)], StopImage.p.ypoints[j + i * (gridX + 1)]);
177 d1 = new Point(StopImage.p.xpoints[j + 1 + i * (gridX + 1)], StopImage.p.ypoints[j + 1 + i * (gridX + 1)]);
178 d2 = new Point(StopImage.p.xpoints[j + 1 + (i + 1) * (gridX + 1)], StopImage.p.ypoints[j + 1 + (i + 1) * (gridX + 1)]);
179 d3 = new Point(StopImage.p.xpoints[j + (i + 1) * (gridX + 1)], StopImage.p.ypoints[j + (i + 1) * (gridX + 1)]);
180
181
182 solveMorph(s0, s1, s2, s3, m0, m1, m2, m3, d0, d1, d2, d3, k);
183 }
184 }
185
186 int Dist(Point a, Point b) {
187 return (int) (Math.sqrt(((b.x - a.x) * (b.x - a.x)) + ((b.y - a.y) * (b.y - a.y))));
188 }
189
190 public void solveMorph(Point s0, Point s1, Point s2, Point s3, Point m0, Point m1, Point m2, Point m3, Point d0, Point d1, Point d2, Point d3, double k1) {
191 double xStart1, xEnd1,yStart1, yEnd1;
192 double xStart2, xEnd2,yStart2, yEnd2;
193 double xStart3, xEnd3,yStart3, yEnd3;
194 double k = 0;
195 short rS, gS, bS, rD, gD, bD;
196
197 int MAX = 0;
198 int MAX1 = 0;
199 int xM, yM, xS, yS, xD, yD;
200
201 MAX = Dist(d0, d1);
202 MAX1 = Dist(d1, d2);
203 if (MAX1 > MAX) MAX = MAX1;
204 MAX1 = Dist(d2, d3);
205 if (MAX1 > MAX) MAX = MAX1;
206 MAX1 = Dist(d3, d0);
207 if (MAX1 > MAX) MAX = MAX1;
208
209 MAX1 = Dist(s0, s1);
210 if (MAX1 > MAX) MAX = MAX1;
211 MAX1 = Dist(s1, s2);
212 if (MAX1 > MAX) MAX = MAX1;
213 MAX1 = Dist(s2, s3);
214 if (MAX1 > MAX) MAX = MAX1;
215 MAX1 = Dist(s3, s0);
216 if (MAX1 > MAX) MAX = MAX1;
217
218 MAX1 = Dist(m0, m1);
219 if (MAX1 > MAX) MAX = MAX1;
220 MAX1 = Dist(m1, m2);
221 if (MAX1 > MAX) MAX = MAX1;
222 MAX1 = Dist(m2, m3);
223 if (MAX1 > MAX) MAX = MAX1;
224 MAX1 = Dist(m3, m0);
225 if (MAX1 > MAX) MAX = MAX1;
226
227 MAX = MAX + 1;
228
229 for (int i = 0; i <= MAX; i++) {
230 k = (double) ((double) i / (double) MAX);
231 xStart1 = linearY(d0.x, d3.x, k);
232 yStart1 = linearY(d0.y, d3.y, k);
233 xEnd1 = linearY(d1.x, d2.x, k);
234 yEnd1 = linearY(d1.y, d2.y, k);
235 xStart2 = linearY(s0.x, s3.x, k);
236 yStart2 = linearY(s0.y, s3.y, k);
237 xEnd2 = linearY(s1.x, s2.x, k);
238 yEnd2 = linearY(s1.y, s2.y, k);
239
240 xStart3 = linearY(m0.x, m3.x, k);
241 yStart3 = linearY(m0.y, m3.y, k);
242 xEnd3 = linearY(m1.x, m2.x, k);
243 yEnd3 = linearY(m1.y, m2.y, k);
244 for (int j = 0; j <= MAX; j++) {
245 k = (double) ((double) j / (double) MAX);
246 xM = (int) (linearY(xStart3, xEnd3, k));
247 yM = (int) (linearY(yStart3, yEnd3, k));
248 xS = (int) (linearY(xStart2, xEnd2, k));
249 yS = (int) (linearY(yStart2, yEnd2, k));
250 xD = (int) (linearY(xStart1, xEnd1, k));
251 yD = (int) (linearY(yStart1, yEnd1, k));
252
253 if ((xS < getImageWidth()) && (yS < getImageHeight()) && (xS >= 0) && (yS >= 0) &&
254 (xD < getImageWidth()) && (yD < getImageHeight()) && (xD >= 0) && (yD >= 0) &&
255 (xM < getImageWidth()) && (yM < getImageHeight()) && (xM >= 0) && (yM >= 0)) {
256
257 rS = (short) shortImageBean.getR()[xS][yS];
258 gS = (short) shortImageBean.getG()[xS][yS];
259 bS = (short) shortImageBean.getB()[xS][yS];
260 rD = (short) shortImageBean.getR()[xD][yD];
261 gD = (short) shortImageBean.getG()[xD][yD];
262 bD = (short) shortImageBean.getB()[xD][yD];
263
264 rm[xM][yM] = (short) linearY(rS, rD, k1);
265 gm[xM][yM] = (short) linearY(gS, gD, k1);
266 bm[xM][yM] = (short) linearY(bS, bD, k1);
267 }
268 }
269 }
270 }
271
272
273 double linearY(double x1, double x2, double t) {
274 double dx = 0;
275 dx = (double) (x2 - x1);
276 return (double) (x1 + (double) (dx * t));
277 }
278
279 public void Properties() {
280 el = new ExpandoLog(new Frame(),
281 "Properties", prompts, defaults, 9);
282 el.setVisible(true);
283 el.setButton.addActionListener(this);
284 }
285
286
287 private void default1() {
288 gridX = 5;
289 gridY = 5;
290 setSize(getImageWidth(), getImageHeight());
291 SourceImage.default1();
292 StopImage.default1();
293 repaint();
294 }
295
296 public static void main(String args[]) {
297 MorphLog mL = new MorphLog(
298 "MorphLog");
299 mL.setSize(150, 150);
300 mL.setVisible(true);
301 }
302
303 }