/*
* $Id$
*
* Copyright (c) 2010 by Joel Uckelman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License (LGPL) as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, copies are available
* at http://www.opensource.org.
*/
package VASSAL.tools.image.tilecache;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
/**
* Reconstitute an image from tile files.
*
* @since 3.2.0
* @author Joel Uckelman
*/
public class TilesToImage {
/**
* Converts tile files to an image file.
*
* @param args the first argument is the path of the basename of the tile
* files, the second argument is the scale factor, the third is the path
* of the PNG to write
*
* @throws IOException if something goes wrong
*/
public static void main(String[] args) throws IOException {
// Oh we have no heads, we have no HEADS!
System.setProperty("java.awt.headless", "true");
final String base = args[0];
final String scale = args[1];
final String dpath = args[2];
Dimension d;
// find the tile in the upper left corner to get tile size
d = TileUtils.size(base + "(0,0)@1:" + scale);
final int tw = d.width;
final int th = d.height;
// find the tile in the lower right corner to get the number of rows
// and columns, as well as the width of the last column and the height
// of the last row
final File bdir = new File(base).getParentFile();
final FileFilter filter = new FileFilter() {
public boolean accept(File pathname) {
return pathname.getPath().startsWith(base);
}
};
final Pattern p = Pattern.compile(base + "\\((\\d+),(\\d+)\\)@1:");
int max_row = 0;
int max_col = 0;
for (File f : bdir.listFiles(filter)) {
final Matcher m = p.matcher(f.getPath());
if (m.lookingAt()) {
final int c = Integer.parseInt(m.group(1));
final int r = Integer.parseInt(m.group(2));
if (c > max_col) max_col = c;
if (r > max_row) max_row = r;
}
}
final int tcols = max_col + 1;
final int trows = max_row + 1;
d = TileUtils.size(base + "(" + max_col + "," + max_row + ")@1:" + scale);
final int tw_last = d.width;
final int th_last = d.height;
// create the new image
final int w = tw*(tcols-1) + tw_last;
final int h = th*(trows-1) + th_last;
final BufferedImage img =
new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = img.createGraphics();
// TODO: We could do this faster by making it multithreaded, since
// writes to the destination image never overlap.
for (int tx = 0; tx < tcols; ++tx) {
for (int ty = 0; ty < trows; ++ty) {
final File tfile =
new File(base + "(" + tx + "," + ty + ")@1:" + scale);
final BufferedImage tile = TileUtils.read(tfile);
g.drawImage(tile, tx*tw, ty*th, null);
}
}
// write the cobbled image
ImageIO.write(img, "PNG", new FileOutputStream(dpath));
}
}