summaryrefslogtreecommitdiff
path: root/tools/Reorganize.java
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Reorganize.java')
-rw-r--r--tools/Reorganize.java198
1 files changed, 198 insertions, 0 deletions
diff --git a/tools/Reorganize.java b/tools/Reorganize.java
new file mode 100644
index 000000000..0b9c86060
--- /dev/null
+++ b/tools/Reorganize.java
@@ -0,0 +1,198 @@
+/* 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;
+
+/**
+ * Tool to reorganize the headgears.
+ */
+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 HAIR_COLORS = 10;
+ private static final int HAIR_FRAMES = 9;
+ private static final int HAIR_SPRITE_WIDTH = 40;
+ private static final int HAIR_SPRITE_HEIGHT = 40;
+
+ 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);
+ }
+
+ // Read the existing frames into a vector
+ Vector<BufferedImage> spriteSet = gridCut(source,
+ HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT,
+ HAIR_FRAMES, 1);
+
+ // Determine minimal rectangle that can still contain the contents of
+ // any frame
+ /*
+ Rectangle cropRect = minimumCropRect(spriteSet);
+
+ if (cropRect == null) {
+ System.out.println(
+ "Error: no optimal crop rect could be determined.");
+ System.exit(1);
+ }
+
+ System.out.println(arg[0] + ": width=\"" +
+ cropRect.width + "\" height=\"" + cropRect.height + "\"");
+ */
+
+ filterHeadgear(spriteSet);
+
+ BufferedImage target = gridDraw(
+ spriteSet,
+ new Rectangle(0, 0, HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT),
+ HAIR_FRAMES - 4, 1);
+
+ // 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 Vector<BufferedImage> gridCut(
+ BufferedImage source,
+ int width, int height, int xFrames, int yFrames)
+ {
+ Vector<BufferedImage> spriteSet = new Vector<BufferedImage>();
+
+ for (int y = 0; y < yFrames; y++) {
+ for (int x = 0; x < xFrames; x++) {
+ BufferedImage sprite = source.getSubimage(
+ x * width,
+ y * height,
+ width,
+ height);
+
+ spriteSet.add(sprite);
+ }
+ }
+
+ return spriteSet;
+ }
+
+ private static BufferedImage gridDraw(Vector<BufferedImage> spriteSet,
+ Rectangle cropRect, int xFrames, int yFrames)
+ {
+ // Create a new image
+ BufferedImage target = new BufferedImage(
+ xFrames * cropRect.width,
+ yFrames * cropRect.height,
+ BufferedImage.TYPE_INT_ARGB);
+
+ // Draw the frames onto the target image
+ Graphics g = target.getGraphics();
+ for (int y = 0; y < yFrames; y++) {
+ for (int x = 0; x < xFrames; x++) {
+ g.drawImage(
+ spriteSet.get(x + xFrames * y).getSubimage(
+ cropRect.x,
+ cropRect.y,
+ cropRect.width,
+ cropRect.height),
+ x * cropRect.width,
+ y * cropRect.height,
+ null);
+ }
+ }
+
+ return target;
+ }
+
+ private static Rectangle minimumCropRect(Vector<BufferedImage> spriteSet)
+ {
+ Rectangle cropRect = null;
+
+ for (BufferedImage sprite : spriteSet) {
+ Rectangle frameCropRect = determineCropRect(sprite);
+
+ if (cropRect == null) {
+ cropRect = frameCropRect;
+ } else {
+ cropRect.add(frameCropRect);
+ }
+ }
+
+ // Make crop rect one pixel larger (since we want an inclusive rect)
+ if (cropRect != null) {
+ cropRect.add(
+ cropRect.x + cropRect.width + 1,
+ cropRect.y + cropRect.height + 1);
+ }
+
+ return cropRect;
+ }
+
+ 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;
+ }
+
+ private static void filterHairstyle(Vector<BufferedImage> spriteSet)
+ {
+ // Remove frame 1, 2, 6 and 7 from each color
+ for (int i = HAIR_COLORS - 1; i >= 0; i--) {
+ spriteSet.remove(i * HAIR_FRAMES + 7);
+ spriteSet.remove(i * HAIR_FRAMES + 6);
+ spriteSet.remove(i * HAIR_FRAMES + 2);
+ spriteSet.remove(i * HAIR_FRAMES + 1);
+ }
+ }
+
+ private static void filterHeadgear(Vector<BufferedImage> spriteSet)
+ {
+ // Remove frame 1, 2, 6 and 7
+ spriteSet.remove(7);
+ spriteSet.remove(6);
+ spriteSet.remove(2);
+ spriteSet.remove(1);
+ }
+}