CDMS/src/CDMS/ImageNavigatorII
diff -u -r1.1 -r1.2
--- Stitcher.java 28 Jul 2010 17:32:33 -0000 1.1
+++ Stitcher.java 28 Jul 2010 22:03:01 -0000 1.2
@@ -6,138 +6,144 @@
import java.io.*;
import javax.imageio.ImageIO;
import java.util.*;
-
+
+/*
+ * Looking in the $path given, this program takes the autorun.txt file and the images of
+ * the form $imageFileName (replace the counting element with "#"), and stitches them
+ * together into larger images. Because an image containing all the stitched images
+ * would be far too large for most computers to handle, these are saved in images of
+ * width and height $tileW and $tileH, labeled "row_col.png." It is recommended that
+ * these are a powers of 2 (Tiler.java has only been extensively tested with these
+ * both set to 2048).
+ *
+ * File Structure:
+ * >Image Set Folder
+ * >gmapviewer.htm [the website navigator file!]
+ * >original_images [place the autorun.txt file and images in this folder before running this program]
+ * >resources [do not touch these files, they are used by the Google API for the navigator]
+ * >stitched_images [stitched images will be saved here]
+ * >tiles [when you run Tiler.java, the tiles for the navigator will be placed here.]
+ *
+ * @author Chris Wilen
+ */
+
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) {
- }
+ Date startDate = new Date();
+ //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/";
+ String autorunFile = "Autorun_IZipG18M_TB_75x3_11May10.txt";
+ String imageFileName = "/"+"IZipG18M_TB_75x3-#.png";
+ String[] lines = getLines(path+"/original_images/"+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<Integer>();
+ ArrayList<Double> ymins = new ArrayList<Double>();
+ ArrayList<Double> xmins = new ArrayList<Double>();
+ ArrayList<Double> moveX = new ArrayList<Double>();
+ double xMin = 1000;
+ int maxCols = 0;
+ double pxSize = 5.452/1000;//3.37085208/620;//x75.3 magnification: 5.452um
+ 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);
+ BufferedImage image = ImageIO.read(new File( path+"/original_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("Offset: {"+(dX-640)+","+(dY-480)+"}");
+ //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;
+ boolean draw = false;
+ 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 minTileRenderX = col*tileW-imgW;
+ double maxTileRenderX = (col+1)*tileW+imgW;
+ double minTileRenderY = row*tileW-imgH;
+ double maxTileRenderY = (row+1)*tileW+imgH;
+ double drawX = c*dX*Math.cos(theta)+(xmins.get(r)-xMin)/pxSize;
+ double drawY = r*dY+c*dX*Math.sin(theta);
+ 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+"/original_images/"+imageFileName.replace("#",""+lastImage);
+ image = ImageIO.read(new File(imagePath));
+ at = AffineTransform.getTranslateInstance(0, 0);
+ 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]++;
+ if(sumR!=0 || sumG!=0 || sumB!=0) draw=true;
+ toStoreRaster.setSample(drawXtoStore, drawYtoStore, 0, sumR);
+ toStoreRaster.setSample(drawXtoStore, drawYtoStore, 1, sumG);
+ toStoreRaster.setSample(drawXtoStore, drawYtoStore, 2, sumB);
+ }
+ }
+ }
+ toStore.setData(toStoreRaster);
+ }
+ }
+ }
+ if (draw==true) ImageIO.write(toStore, "PNG", new File(path+"/stitched_images/"+row+"_"+col+".png"));
+ g2.dispose();
+ }
+ }
-
+ Date endDate = new Date();
+ System.out.println("\nRuntime: "+(endDate.getTime()-startDate.getTime())/1000/60);
}
//takes an input path and returns a list of values split by the SET_PART-REPEAT