package tools.image; import java.awt.Color; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Transparency; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.imageio.ImageIO; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import games.strategy.debug.ClientLogger; import games.strategy.triplea.ui.screen.TileManager; import games.strategy.ui.Util; import games.strategy.util.PointFileReaderWriter; import tools.map.making.JTextAreaOptionPane; /** * For taking a folder of basetiles and putting them back together into an image. */ public class TileImageReconstructor { private static String baseTileLocation = null; private static String imageSaveLocation = null; private static File s_mapFolderLocation = null; private static final String TRIPLEA_MAP_FOLDER = "triplea.map.folder"; private static final JTextAreaOptionPane textOptionPane = new JTextAreaOptionPane(null, "TileImageReconstructor Log\r\n\r\n", "", "TileImageReconstructor Log", null, 500, 300, true, 1, null); private static int sizeX = -1; private static int sizeY = -1; private static Map<String, List<Polygon>> m_polygons = new HashMap<>(); public static void main(final String[] args) throws Exception { handleCommandLineArgs(args); JOptionPane.showMessageDialog(null, new JLabel("<html>" + "This is the TileImageReconstructor, it will reconstruct a single map image from a folder full of " + "basetiles. " + "<br>You must know the size of the map image before you begin, this is normally found in the " + "map.properties file. " + "</html>")); final FileSave baseTileLocationSelection = new FileSave("Where are the Tile Images?", null, s_mapFolderLocation); baseTileLocation = baseTileLocationSelection.getPathString(); if (s_mapFolderLocation == null && baseTileLocationSelection.getFile() != null) { s_mapFolderLocation = baseTileLocationSelection.getFile().getParentFile(); } if (baseTileLocation == null) { System.out.println("You need to select a folder where the basetiles are for this to work"); System.out.println("Shutting down"); System.exit(0); return; } final FileSave imageSaveLocationSelection = new FileSave("Save Map Image As?", null, s_mapFolderLocation, JFileChooser.FILES_ONLY, new File(s_mapFolderLocation, "map.png"), new javax.swing.filechooser.FileFilter() { @Override public boolean accept(final File f) { if (f.isDirectory()) { return false; } return f.getName().endsWith(".png"); } @Override public String getDescription() { return "*.png"; } }); imageSaveLocation = imageSaveLocationSelection.getPathString(); if (imageSaveLocation == null) { System.out.println("You need to choose a name and location for your image file for this to work"); System.out.println("Shutting down"); System.exit(0); return; } final String width = JOptionPane.showInputDialog(null, "Enter the map image's full width in pixels:"); if (width != null) { try { sizeX = Integer.parseInt(width); } catch (final NumberFormatException ex) { // ignore malformed input } } final String height = JOptionPane.showInputDialog(null, "Enter the map image's full height in pixels:"); if (height != null) { try { sizeY = Integer.parseInt(height); } catch (final NumberFormatException ex) { // ignore malformed input } } if (sizeX <= 0 || sizeY <= 0) { System.out.println("Map dimensions must be greater than zero for this to work"); System.out.println("Shutting down"); System.exit(0); return; } if (JOptionPane.showConfirmDialog(null, "Do not draw polgyons.txt file onto your image?\r\n(Default = 'yes' = do not draw)", "Do Not Also Draw Polygons?", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) { try { System.out.println("Load a polygon file"); final String polyName = new FileOpen("Load A Polygon File", s_mapFolderLocation, ".txt").getPathString(); if (polyName != null) { final FileInputStream in = new FileInputStream(polyName); m_polygons = PointFileReaderWriter.readOneToManyPolygons(in); } } catch (final Exception ex) { ClientLogger.logQuietly(ex); } } createMap(); } private static void createMap() { textOptionPane.show(); final GraphicsConfiguration localGraphicSystem = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); final BufferedImage mapImage = localGraphicSystem.createCompatibleImage(sizeX, sizeY, Transparency.TRANSLUCENT); final Graphics graphics = mapImage.getGraphics(); for (int x = 0; (x) * TileManager.TILE_SIZE < sizeX; x++) { for (int y = 0; (y) * TileManager.TILE_SIZE < sizeY; y++) { final String tileName = x + "_" + y + ".png"; final File tileFile = new File(baseTileLocation, tileName); if (tileFile == null || !tileFile.exists()) { continue; } final Image tile = Toolkit.getDefaultToolkit().createImage(tileFile.getPath()); Util.ensureImageLoaded(tile); final Rectangle tileBounds = new Rectangle(x * TileManager.TILE_SIZE, y * TileManager.TILE_SIZE, Math.min((x * TileManager.TILE_SIZE) + TileManager.TILE_SIZE, sizeX), Math.min((y * TileManager.TILE_SIZE) + TileManager.TILE_SIZE, sizeY)); graphics.drawImage(tile, tileBounds.x, tileBounds.y, tileBounds.x + tileBounds.width, tileBounds.y + tileBounds.height, 0, 0, tileBounds.width, tileBounds.height, null); textOptionPane.appendNewLine("Drew " + tileName); } } if (m_polygons != null && !m_polygons.isEmpty()) { graphics.setColor(Color.black); textOptionPane.appendNewLine("Drawing Polygons"); for (final Entry<String, List<Polygon>> entry : m_polygons.entrySet()) { for (final Polygon poly : entry.getValue()) { graphics.drawPolygon(poly.xpoints, poly.ypoints, poly.npoints); } } } textOptionPane.appendNewLine("Saving as " + imageSaveLocation + " ... "); try { ImageIO.write(mapImage, "png", new File(imageSaveLocation)); } catch (final IOException e) { ClientLogger.logQuietly(e); } textOptionPane.appendNewLine("Wrote " + imageSaveLocation); textOptionPane.appendNewLine("\r\nAll Finished!"); textOptionPane.countDown(); textOptionPane.dispose(); JOptionPane.showMessageDialog(null, new JLabel("All Finished")); System.exit(0); } private static String getValue(final String arg) { final int index = arg.indexOf('='); if (index == -1) { return ""; } return arg.substring(index + 1); } private static void handleCommandLineArgs(final String[] args) { // arg can only be the map folder location. if (args.length == 1) { String value; if (args[0].startsWith(TRIPLEA_MAP_FOLDER)) { value = getValue(args[0]); } else { value = args[0]; } final File mapFolder = new File(value); if (mapFolder.exists()) { s_mapFolderLocation = mapFolder; } else { System.out.println("Could not find directory: " + value); } } else if (args.length > 1) { System.out.println("Only argument allowed is the map directory."); } // might be set by -D if (s_mapFolderLocation == null || s_mapFolderLocation.length() < 1) { final String value = System.getProperty(TRIPLEA_MAP_FOLDER); if (value != null && value.length() > 0) { final File mapFolder = new File(value); if (mapFolder.exists()) { s_mapFolderLocation = mapFolder; } else { System.out.println("Could not find directory: " + value); } } } } }