import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import shtick.math.FourierBasis; import shtick.math.FourierSeries; ////////////////////////////////////////////////////// //**************************************************// //* FourierDemo2 Applet *// //* *// //* Version 1.2.1 *// //* Author: Sean M. Cox *// //* Organization: The Shtick *// //* http://www.smcox.com/ *// //* *// //* Demonstrates, in detail, the use of the *// //* Fourier Transform to to morph an image. *// //* *// //**************************************************// ////////////////////////////////////////////////////// public class FourierDemo2 extends Applet implements ActionListener, Runnable{ private byte transDir=0; // Value {-1, 0, 1} specifing direction of change. private int transPos=0; // First harmonic value of original image // to be used. private final int transSteps=15; // Number of steps to take in making tansition. private double[][] sinTable; private double[][] cosTable; private int width; // Image width private int height; // " Height private int transPixels[]; private int fromPixels[]; private int toPixels[]; private String error=""; private Button runButton; private Button moreButton; private Button lessButton; private Image fromImage; private Image transImage; private Image toImage; private FourierSeries[][] fromSeries; private FourierSeries[][] toSeries; private double[] avgAmpChange; private double totalAvgChange; private Thread t; public FourierDemo2(){ lessButton= new Button("Less"); moreButton= new Button("More"); runButton= new Button("Run"); setLayout(null); t=new Thread(this,"Morph Runner"); } public void init() { double[] data; MediaTracker mediaMan=new MediaTracker(this); fromImage=getImage(getDocumentBase(),"famres.gif"); toImage=getImage(getDocumentBase(),"goslib.gif"); mediaMan.addImage(fromImage,0); mediaMan.addImage(toImage,1); add(lessButton); add(moreButton); add(runButton); lessButton.addActionListener(this); moreButton.addActionListener(this); runButton.addActionListener(this); lessButton.setBounds(20,100,lessButton.getPreferredSize().width,lessButton.getPreferredSize().height); moreButton.setBounds(20,150,moreButton.getPreferredSize().width,moreButton.getPreferredSize().height); runButton.setBounds(20,125,runButton.getPreferredSize().width,runButton.getPreferredSize().height); try{ mediaMan.waitForAll(); width=fromImage.getWidth(null); height=fromImage.getHeight(null); if(width<0){ error="Error downloading image to morph."; } FourierBasis basis=new FourierBasis(width); sinTable=basis.getSineBasis(); cosTable=basis.getCosineBasis(); fromPixels=new int[width*height]; transPixels=new int[width*height]; toPixels=new int[width*height]; PixelGrabber pg=new PixelGrabber(fromImage,0,0,width,height,fromPixels,0,width); pg.grabPixels(); pg=new PixelGrabber(toImage,0,0,width,height,toPixels,0,width); pg.grabPixels(); transPixels=fromPixels; data=new double[width]; fromSeries = new FourierSeries[height][3]; toSeries = new FourierSeries[height][3]; for (int x=0;x> (8*c))&0x0FF); } fromSeries[x][c]=new FourierSeries(data,basis); fromSeries[x][c].translate(); for (int y=0;y> (8*c))&0x0FF); } toSeries[x][c]=new FourierSeries(data,basis); toSeries[x][c].translate(); }//for }//for avgAmpChange=new double[basis.getSineBasis().length]; totalAvgChange=0; for (int h=0;htransSteps){ transPos=transSteps; } }//if untranslate(); transImage=createImage(new MemoryImageSource(width, height, transPixels, 0, width)); } private void untranslate() { for (int y=0;y=(totalAvgChange*((double)transPos)/((double)transSteps))){ tally+=(double)(fromSeries[y][c].getCosineSeries()[z]*cosTable[z][x]+fromSeries[y][c].getSineSeries()[z]*sinTable[z][x]); } else{ tally+=(double)(toSeries[y][c].getCosineSeries()[z]*cosTable[z][x]+toSeries[y][c].getSineSeries()[z]*sinTable[z][x]); } ampChangeTally+=avgAmpChange[z]; } } if (tally>255) {tally=255;} else if (tally<0) {tally=0;} transPixels[y*width+x]+=(((int)tally)&0x0FF)<<(8*c); }//for transPixels[y*width+x]|=0xFF000000; }//for }//for } public void actionPerformed(ActionEvent ae) { if (ae.getActionCommand().equals("Less")){ transDir=-1; transUpdate(); repaint(); } if (ae.getActionCommand().equals("More")){ transDir=1; transUpdate(); repaint(); } if (ae.getActionCommand().equals("Run")){ t.start(); } } public void run(){ while(transPos