package ip.raul;
import ip.gui.frames.AnimateFrame;
import ip.gui.dialog.ExpandoLog;
import ip.gui.frames.XformFrame;
import ip.gui.frames.ImageFrame;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MorphLog extends XformFrame
implements ActionListener {
MenuBar mb = new MenuBar();
Menu SettingsMenu = new Menu("Settings");
MenuItem props_mi = addMenuItem(SettingsMenu, "[p]roperties");
MenuItem default_mi = addMenuItem(SettingsMenu, "[d]efault images");
MenuItem morph_mi = addMenuItem(SettingsMenu, "[m]orph");
short rm[][] = new short[0][0];
short gm[][] = new short[0][0];
short bm[][] = new short[0][0];
short rc[][] = new short[0][0];
short gc[][] = new short[0][0];
short bc[][] = new short[0][0];
Image img = null;
Polygon p = new Polygon();
boolean doMorph = false;
GridImage SourceImage = null;
GridImage StopImage = null;
int w = 128;
int h = 128;
int nPoints = 25;
int gridX = 5;
int gridY = 5;
int NumberOfFrames = 50;
boolean busy = false;
String prompts[] = {
"Grid X Elements=",
"Grid Y Elements=",
"Number Of Frames="};
String defaults[] = {
"" + gridX,
"" + gridY,
"" + NumberOfFrames};
ip.gui.dialog.ExpandoLog el = null;
public void actionPerformed(ActionEvent e) {
if (el != null) {
String s[] = el.getUserInput();
gridX = Integer.parseInt(s[0]);
gridY = Integer.parseInt(s[1]);
NumberOfFrames = Integer.parseInt(s[2]);
SourceImage.setGrid(gridX, gridY);
StopImage.setGrid(gridX, gridY);
el = null;
}
if (match(e, morph_mi)) {
Morph();
return;
}
if (match(e, props_mi)) {
Properties();
return;
}
if (match(e, default_mi)) {
default1();
return;
}
super.actionPerformed(e);
}
MorphLog(String title) {
super(title);
init();
mb.add(SettingsMenu);
setMenuBar(mb);
SourceImage = new GridImage("Source Image", Color.red);
StopImage = new GridImage("Stop Image", Color.green);
repaint();
}
private void init() {
}
public void Morph() {
int maxW = 0;
int maxH = 0;
int sourceX, sourceY;
int stopX, stopY;
AnimateFrame af = new AnimateFrame();
double k = 0;
if (getImageWidth() > maxW) maxW = getImageWidth();
if (getImageHeight() > maxH) maxH = getImageHeight();
if (getImageWidth() > maxW) maxW = getImageWidth();
if (getImageHeight() > maxH) maxH = getImageHeight();
setSize(maxW, maxH);
repaint();
rm = new short[maxW][maxH];
gm = new short[maxW][maxH];
bm = new short[maxW][maxH];
rc = new short[maxW][maxH];
gc = new short[maxW][maxH];
bc = new short[maxW][maxH];
setImageHeight(maxH);
setImageWidth(maxW);
setR(rm);
setG(gm);
setB(bm);
short2Image();
img = getImage();
nPoints = (gridX + 1) * (gridY + 1);
p = new Polygon();
for (int j = 0; j < nPoints; j++) {
p.addPoint(SourceImage.p.xpoints[j],
SourceImage.p.ypoints[j]);
}
String files = "seq"; busy = true;
for (int i = 0; i < NumberOfFrames; i++) {
k = (double) ((double) i / (double) (NumberOfFrames - 1));
for (int j = 0; j < nPoints; j++) {
sourceX = SourceImage.p.xpoints[j];
sourceY = SourceImage.p.ypoints[j];
stopX = StopImage.p.xpoints[j];
stopY = StopImage.p.ypoints[j];
p.xpoints[j] = (int) linearY(sourceX, stopX, k);
p.ypoints[j] = (int) linearY(sourceY, stopY, k);
}
applyBilinearMorph(k);
setR(rm);
setG(gm);
setB(bm);
medianCut(256);
img = getImage();
af.addImage(img);
System.out.println((NumberOfFrames - i - 1) + " steps left...");
int outFileNumber = i;
}
af.saveImages();
af.setSize(getImageWidth(), getImageHeight());
af.setVisible(true);
}
public void applyBilinearMorph(double k) {
Point s0,s1,s2,s3,m0,m1,m2,m3,d0,d1,d2,d3;
for (int i = 0; i < gridY; i++)
for (int j = 0; j < gridX; j++) {
s0 = new Point(SourceImage.p.xpoints[j + i * (gridX + 1)], SourceImage.p.ypoints[j + i * (gridX + 1)]);
s1 = new Point(SourceImage.p.xpoints[j + 1 + i * (gridX + 1)], SourceImage.p.ypoints[j + 1 + i * (gridX + 1)]);
s2 = new Point(SourceImage.p.xpoints[j + 1 + (i + 1) * (gridX + 1)], SourceImage.p.ypoints[j + 1 + (i + 1) * (gridX + 1)]);
s3 = new Point(SourceImage.p.xpoints[j + (i + 1) * (gridX + 1)], SourceImage.p.ypoints[j + (i + 1) * (gridX + 1)]);
m0 = new Point(p.xpoints[j + i * (gridX + 1)], p.ypoints[j + i * (gridX + 1)]);
m1 = new Point(p.xpoints[j + 1 + i * (gridX + 1)], p.ypoints[j + 1 + i * (gridX + 1)]);
m2 = new Point(p.xpoints[j + 1 + (i + 1) * (gridX + 1)], p.ypoints[j + 1 + (i + 1) * (gridX + 1)]);
m3 = new Point(p.xpoints[j + (i + 1) * (gridX + 1)], p.ypoints[j + (i + 1) * (gridX + 1)]);
d0 = new Point(StopImage.p.xpoints[j + i * (gridX + 1)], StopImage.p.ypoints[j + i * (gridX + 1)]);
d1 = new Point(StopImage.p.xpoints[j + 1 + i * (gridX + 1)], StopImage.p.ypoints[j + 1 + i * (gridX + 1)]);
d2 = new Point(StopImage.p.xpoints[j + 1 + (i + 1) * (gridX + 1)], StopImage.p.ypoints[j + 1 + (i + 1) * (gridX + 1)]);
d3 = new Point(StopImage.p.xpoints[j + (i + 1) * (gridX + 1)], StopImage.p.ypoints[j + (i + 1) * (gridX + 1)]);
solveMorph(s0, s1, s2, s3, m0, m1, m2, m3, d0, d1, d2, d3, k);
}
}
int Dist(Point a, Point b) {
return (int) (Math.sqrt(((b.x - a.x) * (b.x - a.x)) + ((b.y - a.y) * (b.y - a.y))));
}
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) {
double xStart1, xEnd1,yStart1, yEnd1;
double xStart2, xEnd2,yStart2, yEnd2;
double xStart3, xEnd3,yStart3, yEnd3;
double k = 0;
short rS, gS, bS, rD, gD, bD;
int MAX = 0;
int MAX1 = 0;
int xM, yM, xS, yS, xD, yD;
MAX = Dist(d0, d1);
MAX1 = Dist(d1, d2);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(d2, d3);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(d3, d0);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(s0, s1);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(s1, s2);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(s2, s3);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(s3, s0);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(m0, m1);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(m1, m2);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(m2, m3);
if (MAX1 > MAX) MAX = MAX1;
MAX1 = Dist(m3, m0);
if (MAX1 > MAX) MAX = MAX1;
MAX = MAX + 1;
for (int i = 0; i <= MAX; i++) {
k = (double) ((double) i / (double) MAX);
xStart1 = linearY(d0.x, d3.x, k);
yStart1 = linearY(d0.y, d3.y, k);
xEnd1 = linearY(d1.x, d2.x, k);
yEnd1 = linearY(d1.y, d2.y, k);
xStart2 = linearY(s0.x, s3.x, k);
yStart2 = linearY(s0.y, s3.y, k);
xEnd2 = linearY(s1.x, s2.x, k);
yEnd2 = linearY(s1.y, s2.y, k);
xStart3 = linearY(m0.x, m3.x, k);
yStart3 = linearY(m0.y, m3.y, k);
xEnd3 = linearY(m1.x, m2.x, k);
yEnd3 = linearY(m1.y, m2.y, k);
for (int j = 0; j <= MAX; j++) {
k = (double) ((double) j / (double) MAX);
xM = (int) (linearY(xStart3, xEnd3, k));
yM = (int) (linearY(yStart3, yEnd3, k));
xS = (int) (linearY(xStart2, xEnd2, k));
yS = (int) (linearY(yStart2, yEnd2, k));
xD = (int) (linearY(xStart1, xEnd1, k));
yD = (int) (linearY(yStart1, yEnd1, k));
if ((xS < getImageWidth()) && (yS < getImageHeight()) && (xS >= 0) && (yS >= 0) &&
(xD < getImageWidth()) && (yD < getImageHeight()) && (xD >= 0) && (yD >= 0) &&
(xM < getImageWidth()) && (yM < getImageHeight()) && (xM >= 0) && (yM >= 0)) {
rS = (short) SourceImage.getR()[xS][yS];
gS = (short) SourceImage.getG()[xS][yS];
bS = (short) SourceImage.getB()[xS][yS];
rD = (short) StopImage.getR()[xD][yD];
gD = (short) StopImage.getG()[xD][yD];
bD = (short) StopImage.getB()[xD][yD];
rm[xM][yM] = (short) linearY(rS, rD, k1);
gm[xM][yM] = (short) linearY(gS, gD, k1);
bm[xM][yM] = (short) linearY(bS, bD, k1);
}
}
}
}
double linearY(double x1, double x2, double t) {
double dx = 0;
dx = (double) (x2 - x1);
return (double) (x1 + (double) (dx * t));
}
public void Properties() {
el = new ExpandoLog(new Frame(),
"Properties", prompts, defaults, 9);
el.setVisible(true);
el.setButton.addActionListener(this);
}
private void default1() {
gridX = 5;
gridY = 5;
setSize(getImageWidth(), getImageHeight());
SourceImage.default1();
StopImage.default1();
repaint();
}
public static void main(String args[]) {
MorphLog mL = new MorphLog(
"MorphLog");
mL.setSize(150, 150);
mL.setVisible(true);
}
}