tcr/java/src/client/SkinConverter.java
2025-05-04 20:27:55 +02:00

321 lines
12 KiB
Java
Executable file

package client;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import game.log.Log;
public abstract class SkinConverter {
private static BufferedImage convertSkin(BufferedImage image) {
BufferedImage img = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = img.getGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.drawImage(img, 24, 48, 20, 52, 4, 16, 8, 20, null);
graphics.drawImage(img, 28, 48, 24, 52, 8, 16, 12, 20, null);
graphics.drawImage(img, 20, 52, 16, 64, 8, 20, 12, 32, null);
graphics.drawImage(img, 24, 52, 20, 64, 4, 20, 8, 32, null);
graphics.drawImage(img, 28, 52, 24, 64, 0, 20, 4, 32, null);
graphics.drawImage(img, 32, 52, 28, 64, 12, 20, 16, 32, null);
graphics.drawImage(img, 40, 48, 36, 52, 44, 16, 48, 20, null);
graphics.drawImage(img, 44, 48, 40, 52, 48, 16, 52, 20, null);
graphics.drawImage(img, 36, 52, 32, 64, 48, 20, 52, 32, null);
graphics.drawImage(img, 40, 52, 36, 64, 44, 20, 48, 32, null);
graphics.drawImage(img, 44, 52, 40, 64, 40, 20, 44, 32, null);
graphics.drawImage(img, 48, 52, 44, 64, 52, 20, 56, 32, null);
graphics.dispose();
return img;
}
private static BufferedImage convertSlim(BufferedImage image) {
BufferedImage img = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = img.createGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.setBackground(new Color(0xffffffff, true));
graphics.clearRect(47, 16, 9, 16);
graphics.clearRect(37, 48, 11, 16);
graphics.setBackground(new Color(0x00000000, true));
graphics.clearRect(47, 32, 9, 16);
graphics.clearRect(53, 48, 11, 16);
graphics.drawImage(image, 47, 16, 48, 20, 46, 16, 47, 20, null); //
graphics.drawImage(image, 48, 16, 51, 20, 47, 16, 50, 20, null);
graphics.drawImage(image, 51, 16, 52, 20, 49, 16, 50, 20, null); //
graphics.drawImage(image, 47, 20, 48, 32, 46, 20, 47, 32, null); //
graphics.drawImage(image, 48, 20, 52, 32, 47, 20, 51, 32, null);
graphics.drawImage(image, 53, 20, 56, 32, 51, 20, 54, 32, null);
graphics.drawImage(image, 52, 20, 53, 32, 51, 20, 52, 32, null); //
graphics.drawImage(image, 47, 32, 48, 36, 46, 32, 47, 36, null); //
graphics.drawImage(image, 48, 32, 51, 36, 47, 32, 50, 36, null);
graphics.drawImage(image, 51, 32, 52, 36, 49, 32, 50, 36, null); //
graphics.drawImage(image, 47, 36, 48, 48, 46, 36, 47, 48, null); //
graphics.drawImage(image, 48, 36, 52, 48, 47, 36, 51, 48, null);
graphics.drawImage(image, 53, 36, 56, 48, 51, 36, 54, 48, null);
graphics.drawImage(image, 52, 36, 53, 48, 51, 36, 52, 48, null); //
graphics.drawImage(image, 37, 48, 40, 52, 36, 48, 39, 52, null);
graphics.drawImage(image, 41, 48, 44, 52, 39, 48, 42, 52, null);
graphics.drawImage(image, 40, 48, 41, 52, 39, 48, 40, 52, null); //
graphics.drawImage(image, 37, 52, 40, 64, 36, 52, 39, 64, null);
graphics.drawImage(image, 40, 52, 44, 64, 39, 52, 43, 64, null);
graphics.drawImage(image, 44, 52, 47, 64, 43, 52, 46, 64, null);
graphics.drawImage(image, 47, 52, 48, 64, 45, 52, 46, 64, null); //
graphics.drawImage(image, 53, 48, 56, 52, 52, 48, 55, 52, null);
graphics.drawImage(image, 57, 48, 60, 52, 55, 48, 58, 52, null);
graphics.drawImage(image, 56, 48, 57, 52, 55, 48, 56, 52, null); //
graphics.drawImage(image, 53, 52, 56, 64, 52, 52, 55, 64, null);
graphics.drawImage(image, 56, 52, 60, 64, 55, 52, 59, 64, null);
graphics.drawImage(image, 60, 52, 63, 64, 59, 52, 62, 64, null);
graphics.drawImage(image, 63, 52, 64, 64, 61, 52, 62, 64, null); //
graphics.dispose();
return img;
}
private static void copyData(int[] img1, int[] img2, int xo, int yo, int w, int h, boolean blank, boolean alpha) {
for(int y = yo; y < h+yo; y++) {
for(int x = xo; x < w+xo; x++) {
img2[y*64+x] = blank ? 0x00000000 : (img1[y*64+x] | (alpha ? 0x00000000 : 0xff000000));
}
}
}
private static void copyData(int[] img1, int[] img2, int xo, int yo, int w, int h, int xd, int yd) {
for(int y = 0; y < h; y++) {
for(int x = 0; x < w; x++) {
img2[(yd+y)*64+xd+x] = img1[(yo+y)*64+xo+x];
}
}
}
private static int[] filterImage(int[] img1, int[] img2) {
copyData(img1, img2, 0, 0, 8, 8, true, true);
copyData(img1, img2, 8, 0, 16, 8, false, false);
copyData(img1, img2, 24, 0, 8, 8, true, true);
copyData(img1, img2, 0, 8, 32, 8, false, false);
copyData(img1, img2, 32, 0, 8, 8, true, true);
copyData(img1, img2, 40, 0, 16, 8, false, true);
copyData(img1, img2, 56, 0, 8, 8, true, true);
copyData(img1, img2, 32, 8, 32, 8, false, true);
copyData(img1, img2, 0, 16, 4, 4, true, true);
copyData(img1, img2, 4, 16, 8, 4, false, false);
copyData(img1, img2, 12, 16, 8, 4, true, true);
copyData(img1, img2, 20, 16, 16, 4, false, false);
copyData(img1, img2, 36, 16, 8, 4, true, true);
copyData(img1, img2, 44, 16, 8, 4, false, false);
copyData(img1, img2, 52, 16, 4, 4, true, true);
copyData(img1, img2, 0, 20, 56, 12, false, false);
copyData(img1, img2, 56, 16, 8, 32, true, true);
copyData(img1, img2, 0, 32, 4, 4, true, true);
copyData(img1, img2, 4, 32, 8, 4, false, true);
copyData(img1, img2, 12, 32, 8, 4, true, true);
copyData(img1, img2, 20, 32, 16, 4, false, true);
copyData(img1, img2, 36, 32, 8, 4, true, true);
copyData(img1, img2, 44, 32, 8, 4, false, true);
copyData(img1, img2, 52, 32, 4, 4, true, true);
copyData(img1, img2, 0, 36, 56, 12, false, true);
copyData(img1, img2, 0, 48, 4, 4, true, true);
copyData(img1, img2, 4, 48, 8, 4, false, true);
copyData(img1, img2, 12, 48, 4, 4, true, true);
copyData(img1, img2, 0, 52, 16, 12, false, true);
copyData(img1, img2, 16, 48, 4, 4, true, true);
copyData(img1, img2, 20, 48, 8, 4, false, false);
copyData(img1, img2, 28, 48, 8, 4, true, true);
copyData(img1, img2, 36, 48, 8, 4, false, false);
copyData(img1, img2, 44, 48, 4, 4, true, true);
copyData(img1, img2, 16, 52, 32, 12, false, false);
copyData(img1, img2, 48, 48, 4, 4, true, true);
copyData(img1, img2, 52, 48, 8, 4, false, true);
copyData(img1, img2, 60, 48, 4, 4, true, true);
copyData(img1, img2, 48, 52, 16, 12, false, true);
return img2;
}
private static void relocateIntermediary(int[] img1, int[] img2) {
copyData(img1, img2, 0, 0, 64, 64, 0, 0);
copyData(img1, img2, 4, 16, 8, 4, 20, 48);
copyData(img1, img2, 44, 16, 8, 4, 4, 16);
copyData(img1, img2, 0, 20, 16, 12, 16, 52);
copyData(img1, img2, 40, 20, 16, 12, 0, 20);
copyData(img1, img2, 4, 32, 8, 4, 4, 48);
copyData(img1, img2, 44, 32, 8, 4, 4, 32);
copyData(img1, img2, 0, 36, 16, 12, 0, 52);
copyData(img1, img2, 40, 36, 16, 12, 0, 36);
copyData(img1, img2, 4, 48, 8, 4, 52, 48);
copyData(img1, img2, 20, 48, 8, 4, 36, 48);
copyData(img1, img2, 36, 48, 8, 4, 44, 16);
copyData(img1, img2, 52, 48, 8, 4, 44, 32);
copyData(img1, img2, 0, 52, 16, 12, 48, 52);
copyData(img1, img2, 16, 52, 16, 12, 32, 52);
copyData(img1, img2, 32, 52, 16, 12, 40, 20);
copyData(img1, img2, 48, 52, 16, 12, 40, 36);
}
public static boolean convertSkin(File source, File dir, boolean slim) {
BufferedImage img;
try {
img = ImageIO.read(source);
}
catch(IOException e) {
Log.JNI.error(e, "Konnte kein Bild von " + source + " laden");
return false;
}
if(img == null) {
Log.JNI.warn("Konnte kein Bild von " + source + " laden");
return false;
}
Log.JNI.info("Bild von " + source + " geladen");
if(img.getWidth() == 64 && img.getHeight() == 32) {
img = convertSkin(img);
Log.JNI.info("Skin " + source + " konvertiert");
}
else if(img.getWidth() != 64 || img.getHeight() != 64) {
Log.JNI.warn("Falsche Bildgröße von " + source + ": " + img.getWidth() + "x" + img.getHeight());
return false;
}
String name = source.getName();
int ext = name.lastIndexOf('.');
if(ext >= 0)
name = name.substring(0, ext);
if(name.isEmpty())
name = "skin";
if(slim) {
img = convertSlim(img);
Log.JNI.info("Skin " + source + " von 'Slim' konvertiert");
if(!name.startsWith("slim_"))
name = "slim_" + name;
}
File file = new File(dir, name + ".png");
int z = 1;
while(file.exists()) {
file = new File(dir, name + "_" + (++z) + ".png");
}
// Graphics2D g = img.createGraphics();
// g.setBackground(new Color(0x7fff00ff, true));
// g.clearRect(0, 0, 64, 64);
int[] data = img.getRGB(0, 0, 64, 64, new int[64*64], 0, 64);
int[] data2 = new int[data.length];
relocateIntermediary(data, data2);
data = data2;
filterImage(data, data);
img.setRGB(0, 0, 64, 64, data, 0, 64);
try {
ImageIO.write(img, "png", file);
}
catch(Exception e) {
Log.JNI.error(e, "Konnte Bild nicht speichern");
return false;
}
Log.JNI.info("Skin " + source + " gespeichert als " + file.getName());
return true;
}
// public static void main(String[] args) {
// if(args.length < 1) {
// System.err.println("Verwendung: SkinConverter [-s | -n | -i] <Skin-Datei | Ordner ...>");
// System.exit(1);
// }
// int n = 0;
// boolean slim = false;
//// boolean intermediary = false;
// for(String file : args) {
// if(file.equals("-s")) {
// slim = true;
// continue;
// }
//// else if(file.equals("-i")) {
//// intermediary = true;
//// continue;
//// }
// else if(file.equals("-n")) {
// slim = false;
//// intermediary = false;
// continue;
// }
// else if(new File(file).isDirectory()) {
// String[] files = new File(file).list();
// if(files != null && files.length > 0) {
// for(int z = 0; z < files.length; z++) {
// files[z] = file + File.separator + files[z];
// }
// if(slim) { // || intermediary) {
// String[] files2 = new String[files.length + /* (slim && intermediary ? 2 : */ 1]; // )];
// int pos = 0;
// if(slim)
// files2[pos++] = "-s";
//// if(intermediary)
//// files2[pos++] = "-i";
// System.arraycopy(files, 0, files2, pos, files.length);
// files = files2;
// }
// main(files);
// }
// continue;
// }
// else if(file.endsWith("-converted.png"))
// continue;
// String out = (file.endsWith(".png") ? file.substring(0, file.length() - 4) : file) + "-converted.png";
// BufferedImage img;
// try {
// img = ImageIO.read(new File(file));
// }
// catch(Exception e) {
// System.err.println("Konnte Bild '" + file + "' nicht laden");
// e.printStackTrace();
// continue;
// }
// if(img == null) {
// System.err.println("Konnte Bild '" + file + "' nicht öffnen");
// continue;
// }
// if(img.getWidth() == 64 && img.getHeight() == 32) {
// img = convertSkin(img);
// System.out.println("Skin '" + file + "' von 64x32 nach 64x64 konvertiert");
// }
// else if(img.getWidth() != 64 || img.getHeight() != 64) {
// System.err.println("Falsche Bildgröße für '" + file + "': " + img.getWidth() + "x" + img.getHeight());
// continue;
// }
// if(slim) {
// img = convertSlim(img);
// System.out.println("Skin '" + file + "' von 'Slim' nach 64x64/'Schlank' konvertiert");
// }
// int[] data = img.getRGB(0, 0, 64, 64, new int[64*64], 0, 64);
//// if(intermediary) {
// int[] data2 = new int[data.length];
// relocateIntermediary(data, data2);
// data = data2;
//// }
//// else {
// filterImage(data, data);
//// }
// img.setRGB(0, 0, 64, 64, data, 0, 64);
// try {
// ImageIO.write(img, "png", new File(out));
// }
// catch(Exception e) {
// System.err.println("Konnte Bild '" + out + "' nicht speichern");
// e.printStackTrace();
// continue;
// }
// System.out.println("Skin von '" + file + "' nach '" + out + "' konvertiert");
// n++;
// }
// if(n > 0)
// System.out.println(n + " Skins wurden konvertiert");
// }
}