I know I mentioned putting together a image tiling Processing library, but so far I haven’t had time. To start at the wrong end, here’s the image stitching code for putting together the tiles once they’ve been generated. Hopefully that will be of use to some people.
Note that you might run into memory problems if you use huge tiles. Processing 0119 has a new “Set maximum memory” preference that easily takes care of this problem (see File > Preferences).
See the Processing forums for some sample code creating tiles, posted by user “surelyyoujest”.
Update: I’ve put together a proper class for this tiling technique. Have a look at aTileSaver.pde.
Source code - ImageStitcher.pde
// ImageStitcher.pde
// Marius Watz - http://workshop.evolutionzone.com
//
// Takes a folder of tile images and puts it together in one
// big image. Just place a folder in the your sketch folder,
// and change the file prefix and suffix in the code below.
// Change these according to your needs
// The folder should be in the base of your sketch
// (not the data folder)
String fileFolder="test";
String filePrefix="Kugel_";
String fileSuffix="png";
PImage tmp,big;
boolean done=false;
int resx,resy,tiledim,loadcnt=0;
String filename;
long start=-1,elapsed,remain;
float fract;
void setup() {
size(300,300);
}
public void draw() {
if(!done) stitch();
}
// Does the actual job
public void stitch() {
println("ImageStitcher..."+
"------------------------------------------");
filename=filePrefix+" tiled."+fileSuffix;
fileFolder=savePath(fileFolder);
println("Folder: "+fileFolder);
println("Output: "+filename);
// Find all files that match the prefix and suffix
FilenameFilter filter=
new TileNameFilter(filePrefix,fileSuffix);
String [] files=new File(fileFolder).list();
// Assuming an equal number of tiles in X and Y directions,
// get the square root to get tile dimensions
tiledim=(int)sqrt(files.length);
filename=filePrefix+nf(loadcnt,2)+"."+fileSuffix;
load(filename);
int idx,idy;
for(int i=0; i< tiledim*tiledim; i++) {
filename=filePrefix+nf(loadcnt,2)+"."+fileSuffix;
if(i>0) load(filename);
idx=(i%tiledim);
idy=(i/tiledim);
big.set(idx*resx,idy*resy, tmp);
}
long savestart=millis();
filename=filePrefix+" tiled."+fileSuffix;
print("\nSaving "+filename+".");
big.save(fileFolder+File.separator+filename);
elapsed=millis()-savestart;
println(" Done. Elapsed: "+milliStr(elapsed));
elapsed=millis()-start;
println("100% Done. Time taken: "+milliStr(elapsed)+".");
done=true;
exit();
}
public void load(String _file) {
if(start==-1) start=millis();
tmp=loadImage(fileFolder+"/"+filename);
// If first tile, get resolution and set up big image
if(loadcnt==0) {
resx=tmp.width;
resy=tmp.height;
println("Tiles: "+tiledim+" x "+tiledim);
println("Tile image size: "+tmp.width+" x "+tmp.height);
println();
big=new PImage(resx*tiledim,resy*tiledim);
}
loadcnt++;
fract=(float)loadcnt/(tiledim*tiledim);
print(nf((int)(fract*100),3)+"% "+filename+"");
elapsed=millis()-start;
remain=(long) (((float)elapsed/(float)loadcnt)*
tiledim*tiledim-loadcnt);
println(" | "+milliStr(elapsed)+" elapsed, "+
milliStr(remain)+" remaining.");
}
public String milliStr(long milli) {
int min=(int)(milli/(1000*60));
milli-=(1000*60)*min;
int sec=(int)(milli/1000);
return ""+nf(min,2)+":"+nf(sec,2);
}
// Accepts or rejects filenames
class TileNameFilter implements FilenameFilter {
String prefix,suffix;
public TileNameFilter(String _pre,String _suff) {
prefix=_pre;
suffix=_suff;
}
public boolean accept(File dir,String name) {
return (name.startsWith(prefix) &&
name.endsWith(suffix));
}
}





[...] printing abilities should also be [...]