CDMS/src
diff -N Stitcher.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Stitcher.java 23 Jul 2010 19:49:58 -0000 1.1
@@ -0,0 +1,156 @@
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.*;
+import java.io.*;
+import javax.imageio.ImageIO;
+import java.util.*;
+
+public class Stitcher {
+ public static void main(String[] args) throws IOException {
+ try {
+ //read in the file and create a list of command lines (split by SET_PART_REPEAT)(dont use arg 0)
+ String path = "/Users/chriswilen/Documents/Work/Summer_2010/IZipG18M_TB_75x3/tiles/gmapviewer/dropbox";
+ String autorunFile = "/origional_images/"+"Autorun_IZipG18M_TB_75x3_11May10.txt";
+ String imageFileName = "/"+"IZipG18M_TB_75x3-#.png";
+ String[] lines = getLines(path+autorunFile);
+
+ //split the arguments of each line into a list of arguments: number of repeats in row, corrected start X value
+ //also, declares some relevant variables: minimum start x, pixel size, maximum number of repeats
+ ArrayList<Integer> cols = new ArrayList();
+ ArrayList<Double> ymins = new ArrayList();
+ ArrayList<Double> xmins = new ArrayList();
+ ArrayList<Double> moveX = new ArrayList();
+ double xMin = 1000;
+ int maxCols = 0;
+ double pxSize = 3.37085208/620;//1.396/100;
+ for (int i=1; i<lines.length; i++){
+ int repeat = Integer.parseInt(lines[i].split(",")[1]);
+ cols.add(repeat);
+ moveX.add( Double.parseDouble(lines[i].split(",")[3])*2.54*10 );
+ double currentXMin = Double.parseDouble(lines[i].split(",")[11]);
+ xmins.add(currentXMin);
+ double currentYMin = Double.parseDouble(lines[i].split(",")[12]);
+ ymins.add(currentYMin);
+ if (currentXMin<xMin) xMin = currentXMin;
+ if (repeat>maxCols) maxCols = repeat;
+ }
+
+ //declare variables
+ /*********************/
+ double theta = Math.atan(3/640);//Math.toRadians(0.0);
+ BufferedImage image = ImageIO.read(new File( path+"/origional_images/"+imageFileName.replace("#","1") ));
+ int imgW = image.getWidth();
+ int imgH = image.getHeight();
+ int tileW = 2048;
+ int tileH = 2048;
+ double dX = moveX.get(0)/pxSize;
+ double dY = (ymins.get(0)-ymins.get(1))/pxSize;
+ System.out.println("{"+dX+","+dY+"}");
+ //find size of image holder and make holder
+ int holderW = (int)Math.ceil(imgW*Math.cos(theta)+imgH*Math.sin(theta));
+ int holderH = (int)Math.ceil(imgW*Math.sin(theta)+imgH*Math.cos(theta));
+ BufferedImage holder = new BufferedImage(holderW, holderH, image.getType());
+ //find size of total stitched image
+ double totalW = (maxCols-1)*dX + imgW*Math.cos(theta) + imgH*Math.sin(theta);
+ double totalH = (lines.length-1)*dX + imgW*Math.sin(theta) + imgH*Math.cos(theta);
+ AffineTransform at;
+ /*********************/
+ for (int row=0;row<Math.ceil(totalH/tileH); row++) {
+ for (int col=0;col<Math.ceil(totalW/tileW); col++) {
+ System.out.println("new tile("+row+","+col+")");
+ //figure out which images to use
+ //make a tiled image square
+ //write the image to toStore
+ BufferedImage toStore = new BufferedImage(tileW, tileH, image.getType());
+ WritableRaster toStoreRaster = toStore.getRaster().createCompatibleWritableRaster();
+ int[][] layers = new int[tileW][tileH];
+ Graphics2D g2 = holder.createGraphics();
+ int lastImage = 0;
+ for (int r=0; r<lines.length-1; r++) {
+ int nCols = cols.get(r)+1;
+ for (int c=0; c<nCols; c++) {
+ //find out if the img might have a part in the tile
+ double imgDiagonal = Math.sqrt(Math.pow(imgW, 2)+Math.pow(imgH, 2));
+ double minTileRenderX = col*tileW-imgDiagonal;
+ double maxTileRenderX = (col+1)*tileW+imgDiagonal;
+ double minTileRenderY = row*tileW-imgDiagonal;
+ double maxTileRenderY = (row+1)*tileW+imgDiagonal;
+ double drawX = c*dX+(xmins.get(r)-xMin)/pxSize;
+ double drawY = r*dY;
+ lastImage++;
+ //if it is in the tile, make a square with the image tilted appropriately
+ if (drawX>minTileRenderX && drawX<maxTileRenderX && drawY>minTileRenderY && drawY<maxTileRenderY) {
+ String imagePath = path+"/origional_images/"+imageFileName.replace("#",""+lastImage);
+ image = ImageIO.read(new File(imagePath));
+ at = AffineTransform.getTranslateInstance(imgH*Math.sin(theta), holderH-imgH);
+ at.rotate(-theta, 0, imgH);
+ g2.drawRenderedImage(image, at);
+
+ WritableRaster holderRaster = holder.getRaster();
+
+ //write the square with the tilted image to toStore, averaging with any values already there
+ for (int y=0; y < holderH; ++y) {
+ for (int x=0; x < holderW; ++x) {
+ int drawXtoStore = (int)Math.round(drawX-col*tileW+x);
+ int drawYtoStore = (int)Math.round(drawY-row*tileH+y);
+ if (drawXtoStore > 0 && drawXtoStore < tileW && drawYtoStore > 0 && drawYtoStore < tileH) {
+ double sumR = toStoreRaster.getSample(drawXtoStore, drawYtoStore, 0);
+ double sumG = toStoreRaster.getSample(drawXtoStore, drawYtoStore, 1);
+ double sumB = toStoreRaster.getSample(drawXtoStore, drawYtoStore, 2);
+ double multiplier = 1;
+ if (x<20) { multiplier = 1-x/20; }
+ if (x>(holderW-20)) { multiplier = (1/20)*(x-(imgW-20)); }
+ int z = layers[drawXtoStore][drawYtoStore];
+ sumR = (z*sumR + multiplier*holderRaster.getSample(x, y, 0))/(z+1);
+ sumG = (z*sumG + multiplier*holderRaster.getSample(x, y, 1))/(z+1);
+ sumB = (z*sumB + multiplier*holderRaster.getSample(x, y, 2))/(z+1);
+ layers[drawXtoStore][drawYtoStore]++;
+ /*sumR += holderRaster.getSample(x, y, 0);
+ sumG += holderRaster.getSample(x, y, 1);
+ sumB += holderRaster.getSample(x, y, 2);*/
+ toStoreRaster.setSample(drawXtoStore, drawYtoStore, 0, sumR);
+ toStoreRaster.setSample(drawXtoStore, drawYtoStore, 1, sumG);
+ toStoreRaster.setSample(drawXtoStore, drawYtoStore, 2, sumB);
+ }
+ }
+ }
+ /*for (int ypx=0; ypx < tileW; ypx++) {
+ for (int xpx=0; xpx < tileW; xpx++) {
+ int divisor = layers[xpx][ypx];
+ if (divisor!=0) {
+ toStoreRaster.setSample(xpx, ypx, 0, toStoreRaster.getSample(xpx, ypx, 0)/divisor);
+ toStoreRaster.setSample(xpx, ypx, 1, toStoreRaster.getSample(xpx, ypx, 1)/divisor);
+ toStoreRaster.setSample(xpx, ypx, 2, toStoreRaster.getSample(xpx, ypx, 2)/divisor);
+ }
+ }
+ }*/
+ toStore.setData(toStoreRaster);
+ }
+ }
+ }
+ ImageIO.write(toStore, "PNG", new File(path+"/stitched_tiles/tile"+row+"_"+col+".png"));
+ g2.dispose();
+ }
+ }
+ } catch (IOException e) {
+ }
+
+
+ }
+
+ //takes an input path and returns a list of values split by the SET_PART-REPEAT
+ public static String[] getLines(String path) {
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(path));
+ String str;
+ String text = "";
+ while ((str = in.readLine()) != null) {
+ text += "\n"+str;
+ }
+ in.close();
+ String[] lines = text.split("SET_PART_REPEAT");
+ return lines;
+ } catch (IOException e) {System.out.println("File could not be read"); return null;}
+ }
+
+}