summaryrefslogtreecommitdiff
path: root/tools/Reorganize.java
blob: 19a17b9915009f76ca307ce584dd09a586679854 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* Reorganize (c) 2006 Bjørn Lindeijer
 * License: GPL, v2 or later
 */

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.Vector;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;

/**
 * Very simple tool to reorganize the monster spritesets.
 */
public class Reorganize
{
    private static final int SPRITE_WIDTH = 60;
    private static final int SPRITE_HEIGHT = 60;
    private static final int FRAMES = 10;
    private static final int DIRECTIONS = 4;
    private static final int TRANSPARENT = new Color(255, 0, 255).getRGB();

    public static void main(String[] arg)
    {
        if (arg.length != 2) {
            System.out.println("Usage:\n   java Reorganize [source] [target]");
            return;
        }

        BufferedImage source = null;
        try {
            source = ImageIO.read(new File(arg[0]));
        } catch (IOException e) {
            System.out.println("Error while trying to read " + arg[0] + ".");
            e.printStackTrace();
            System.exit(1);
        }

        Rectangle cropRect = null;

        // Read the existing frames into a vector and determine minimal
        // rectangle that still can contain the contents of any frame.
        Vector<BufferedImage> spriteSet = new Vector<BufferedImage>();
        for (int x = 0; x < DIRECTIONS; x++) {
            for (int y = 0; y < FRAMES; y++) {
                BufferedImage sprite = source.getSubimage(
                        x * SPRITE_WIDTH,
                        y * SPRITE_HEIGHT,
                        SPRITE_WIDTH,
                        SPRITE_HEIGHT);

                spriteSet.add(sprite);

                Rectangle frameCropRect = determineCropRect(sprite);

                if (cropRect == null) {
                    cropRect = frameCropRect;
                } else {
                    cropRect.add(frameCropRect);
                }
            }
        }

        if (cropRect == null) {
            System.out.println(
                    "Error: no optimal crop rect could be determined.");
            System.exit(1);
        }

        // Make crop rect one pixel larger (since we want an inclusive rect)
        cropRect.add(
                cropRect.x + cropRect.width + 1,
                cropRect.y + cropRect.height + 1);

        System.out.println(arg[0] + ": width=\"" +
                cropRect.width + "\" height=\"" + cropRect.height + "\"");

        // Create a new image (with frame direction flipped)
        BufferedImage target = new BufferedImage(
                FRAMES * cropRect.width,
                DIRECTIONS * cropRect.height,
                BufferedImage.TYPE_INT_ARGB);

        // Draw the frames onto the target image
        Graphics g = target.getGraphics();
        for (int y = 0; y < DIRECTIONS; y++) {
            for (int x = 0; x < FRAMES; x++) {
                g.drawImage(
                        spriteSet.get(x + FRAMES * y).getSubimage(
                            cropRect.x,
                            cropRect.y,
                            cropRect.width,
                            cropRect.height),
                        x * cropRect.width,
                        y * cropRect.height,
                        null);
            }
        }

        // Save the target image
        try {
            ImageIO.write(target, "png", new File(arg[1]));
        } catch (IOException e) {
            System.out.println("Error while trying to write " + arg[1] + ".");
            e.printStackTrace();
            System.exit(1);
        }
    }

    private static Rectangle determineCropRect(BufferedImage image)
    {
        // Loop through all the pixels, ignoring transparent ones.
        Rectangle rect = null;

        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                int color = image.getRGB(x, y);

                if (color != TRANSPARENT && (color & 0xFF000000) != 0) {
                    if (rect == null) {
                        rect = new Rectangle(x, y, 0, 0);
                    } else {
                        rect.add(x, y);
                    }
                }
            }
        }

        return rect;
    }
}