1 /***************************************************************************
2  *               (C) Copyright 2011-2019 - Faiumoni e. V.                  *
3  ***************************************************************************
4  ***************************************************************************
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 
13 package games.stendhal.tools.map;
14 
15 import java.awt.Color;
16 import java.awt.Graphics2D;
17 import java.awt.RenderingHints;
18 import java.awt.image.BufferedImage;
19 import java.io.File;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStream;
23 
24 import javax.imageio.ImageIO;
25 
26 /**
27  * splits an image
28  *
29  * @author hendrik
30  */
31 public class ImageSplit {
32     private final String imageFilename;
33     private final String targetFolder;
34     private final String prefix;
35     private final int tileSizeSource;
36     private final int tileSizeTarget;
37     private final int offsetX;
38     private final int offsetY;
39     private final int cutOff;
40 
41     /**
42      * creates a new ImageSplit
43      *
44      * @param imageFilename image to split
45      * @param targetFolder  target folder to store the split image ilfes
46      * @param prefix prefix for file names e.g. zoom level
47      * @param tileSizeTarget size in px for the target files
48      * @param offsetX offset for the x-coordinate in the target filenames
49      * @param offsetY offset for the y-coordinate in the target filenames
50      * @param cutOff number of pixels to cut of at each side of the original image
51      */
ImageSplit(String imageFilename, String targetFolder, String prefix, int tileSizeSource, int tileSizeTarget, int offsetX, int offsetY, int cutOff)52     public ImageSplit(String imageFilename, String targetFolder, String prefix, int tileSizeSource, int tileSizeTarget, int offsetX, int offsetY, int cutOff) {
53         this.imageFilename = imageFilename;
54         this.targetFolder = targetFolder;
55         this.prefix = prefix;
56         this.tileSizeSource = tileSizeSource;
57         this.tileSizeTarget = tileSizeTarget;
58         this.offsetX = offsetX;
59         this.offsetY = offsetY;
60         this.cutOff = cutOff;
61     }
62 
63     /**
64      * splits the large image into smaller ones
65      * @throws IOException
66      */
split()67     public void split() throws IOException {
68         System.out.println(prefix);
69         BufferedImage img = ImageIO.read(new File(imageFilename));
70         Color bgColor = new Color(255, 255, 255);
71         for (int x = 0; x < divRoundingUp(img.getWidth(), tileSizeSource); x++) {
72             for (int y = 0; y < divRoundingUp(img.getHeight(), tileSizeSource); y++) {
73                 BufferedImage target = new BufferedImage(tileSizeTarget, tileSizeTarget, BufferedImage.TYPE_INT_RGB);
74                 Graphics2D graphics = target.createGraphics();
75                 graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
76                 graphics.setColor(bgColor);
77                 graphics.fillRect(0, 0, tileSizeTarget, tileSizeTarget);
78                 graphics.drawImage(img, 0, 0, tileSizeTarget, tileSizeTarget,
79                     x * tileSizeSource + cutOff, y * tileSizeSource + cutOff,
80                     (x+1) * tileSizeSource + cutOff, (y+1) * tileSizeSource + cutOff,
81                 bgColor, null);
82                 OutputStream out = new FileOutputStream(targetFolder + "/" + prefix + (x + offsetX) + "-" + (y + offsetY) + ".png");
83                 ImageIO.write(target, "png", out);
84                 out.close();
85                 graphics.dispose();
86             }
87         }
88     }
89 
90     /**
91      * an integer division which rounds up
92      *
93      * @param i number to divide
94      * @param j number to divide by
95      * @return result
96      */
divRoundingUp(int i, int j)97     public static int divRoundingUp(int i, int j) {
98         int res = i / j;
99         if (i % j > 0) {
100             res++;
101         }
102         return res;
103     }
104 
105     /**
106      * entrance point
107      *
108      * @param args command line arguments.
109      * @throws IOException
110      */
main(String[] args)111     public static void main(String[] args) throws IOException {
112         new ImageSplit("/tmp/world.png", "/tmp/map", "0-", 8192, 256, 0, 0, 64).split();
113         new ImageSplit("/tmp/world.png", "/tmp/map", "1-", 4096, 256, 0, 0, 64).split();
114         new ImageSplit("/tmp/world.png", "/tmp/map", "2-", 2048, 256, 0, 0, 64).split();
115         new ImageSplit("/tmp/world.png", "/tmp/map", "3-", 1024, 256, 0, 0, 64).split();
116         new ImageSplit("/tmp/world.png", "/tmp/map", "4-",  512, 256, 0, 0, 64).split();
117         new ImageSplit("/tmp/world-large.png", "/tmp/map", "5-", 1024, 256, 0, 0, 256).split();
118         new ImageSplit("/tmp/world-large.png", "/tmp/map", "6-", 512, 256, 0, 0, 256).split();
119         new ImageSplit("/tmp/world-large.png", "/tmp/map", "7-", 256, 256, 0, 0, 256).split();
120     }
121 }
122