FL
Pokémon Island Creator
- 2,544
- Posts
- 14
- Years
- Seen yesterday
This is the code that I made to resize, divide and correctly format for Essentials use the Chaos Rush sprites at https://www.pokecommunity.com/threads/320775. There some useful methods for image manipulation.
Code:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
/**
* This class facilitates the image manipulation.
* Use factoryImageObject to create a instance loading from a string with the path.
* An example that doubles the image size: <br>
*
* ImageObject variableNameHere = ImageObject.factoryImageObject("imagename.png");
* variableNameHere.multiplySize(2);
* variableNameHere.writeFile("newimagename.png");
*
* @author FL
**/
public class ImageObject implements Cloneable{
private int width;
private int height;
private int[][][] rgbaArray;
private ImageObject(int width, int height){
this.width = width;
this.height = height;
rgbaArray = new int[width][height][4];
}
/**
* Factory method that reads the file from a path
**/
public static ImageObject factoryImageObject(String filename) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new File(filename));
ImageObject ret = new ImageObject(bufferedImage.getWidth(),bufferedImage.getHeight());
for (int line = 0; line < ret.height; line++) {
for (int column = 0; column < ret.width; column++) {
Color pixel = new Color(bufferedImage.getRGB(column, line),true);
ret.rgbaArray[column][line][0] = pixel.getRed();
ret.rgbaArray[column][line][1] = pixel.getGreen();
ret.rgbaArray[column][line][2] = pixel.getBlue();
ret.rgbaArray[column][line][3] = pixel.getAlpha();
}
}
return ret;
}
/**
* Saves the image at a filename location.
**/
public void writeFile(String filename) throws IOException {
File file = new File(filename);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
for (int line = 0; line < height; line++) {
for (int column = 0; column < width; column++) {
int r = rgbaArray[column][line][0];
int g = rgbaArray[column][line][1];
int b = rgbaArray[column][line][2];
int a = rgbaArray[column][line][3];
Color pixel = new Color(r, g, b,a);
bufferedImage.setRGB(column, line, pixel.getRGB());
}
}
String[] splited = filename.split(Pattern.quote(".")); // Split at "." to get the extension
String extension = splited[splited.length-1].toUpperCase();
ImageIO.write(bufferedImage, extension, file);
}
/**
* Concatenates imageObjects horizontally or vertically to create a new instance.
**/
public ImageObject(ImageObject[] imageObjectArray, boolean horizontally){
int number = imageObjectArray.length;
// Define size
width = imageObjectArray[0].width;
height = imageObjectArray[0].height;
for (int i = 1; i < number; i++) {
if(horizontally){
width+=imageObjectArray[i].width;
}else{
height+=imageObjectArray[i].height;
}
}
rgbaArray = new int[width][height][4];
// Combine
for (int i = 0; i < number; i++) {
for (int line = 0; line < height; line++) {
for (int column = 0; column < width; column++) {
int x = column;
int y = line;
if(horizontally){
x += i*width;
}else{
y += i*height;
}
for (int color = 0; color < 4; color++) {
rgbaArray[x][y][color] = imageObjectArray[i].rgbaArray[column][line][color];
}
}
}
}
}
/**
* Divides the image in equals proportions
**/
public ImageObject[] divide(int number, boolean horizontally){
ImageObject[] ret = new ImageObject[number];
for (int i = 0; i < number; i++) {
ret[i] = new ImageObject(horizontally ? width/number : width, horizontally ? height : height/number);
for (int line = 0; line < ret[i].height; line++) {
for (int column = 0; column < ret[i].width; column++) {
int x = column;
int y = line;
if(horizontally){
x += i*width/number;
}else{
y += i*height/number;
}
for (int color = 0; color < 4; color++) {
ret[i].rgbaArray[column][line][color] = rgbaArray[x][y][color];
}
}
}
}
return ret;
}
/**
* Resize the image size.
* Only accept multipler divisors like 2, 4, 0.5, 0.25
**/
public void multiplySize(double factor){
width *= factor;
height *= factor;
int multipler = factor > 1 ? (int)Math.round(factor) : 1;
int divider = factor < 1 ? (int)Math.round(1/factor) : 1;
int[][][] rgbaArrayNew = new int[width][height][4];
for (int line = 0; line < height; line++) {
for (int column = 0; column < width; column++) {
for (int color = 0; color < 4; color++) {
rgbaArrayNew[column/divider][line/divider][color] = rgbaArray[column/multipler][line/multipler][color];
}
}
}
rgbaArray = rgbaArrayNew;
}
/**
* Remove the background.
* Detects the background as the color that the most appears at the first line.
*
* @return Number of pixel affected.
**/
public int removeBackground(){
return makeBackgroundTransparent(pickBackgroundRGB(0,0,width-1,0));
}
/**
* Picks the pixel that most appears at the param coordinates at image
**/
protected int[] pickBackgroundRGB(int xstart, int ystart, int xend, int yend){
List <int[]> firstLine = new ArrayList<int[]>();
for(int y=ystart;y<=yend;y++){
for(int x=xstart;x<=xend;x++){
firstLine.add(new int[]{rgbaArray[x][y][0],rgbaArray[x][y][1],rgbaArray[x][y][2]});
}
}
int rgbBackground[] = new int[3];
int backgroundOccurrences = 0;
while(!firstLine.isEmpty()){
int rgbBackgroundNew[] = firstLine.get(0);
int backgroundOccurrencesNew = 0;
for(int i=0;i<firstLine.size();i++){
int array[] = firstLine.get(i);
if(rgbBackgroundNew[0]==array[0] && rgbBackgroundNew[1]==array[1] && rgbBackgroundNew[2]==array[2]){
backgroundOccurrencesNew++;
firstLine.remove(i--);
}
}
if(backgroundOccurrencesNew>backgroundOccurrences){
rgbBackground = rgbBackgroundNew;
backgroundOccurrences = backgroundOccurrencesNew;
}
}
return rgbBackground;
}
/**
* Search for every rgb equals to rgbTransparent at set the alpha to minimum, making it transparent.
*
* @return Number of pixel affected.
**/
public int makeBackgroundTransparent(int[] rgbTransparent){
int ret = 0;
for (int line = 0; line < height; line++) {
for (int column = 0; column < width; column++) {
boolean equals = true;
for(int color=0;color<rgbTransparent.length;color++){
if(rgbaArray[column][line][color]!=rgbTransparent[color])
equals = false;
}
if(equals){
rgbaArray[column][line][3]=0;
ret++;
}
}
}
return ret;
}
public int makeBackgroundTransparent(int r, int g, int b){
return makeBackgroundTransparent(new int[]{r,g,b});
}
/**
* Increase or decrease the image size.
* Don't mix positive and negative numbers!
**/
public void addSize(int left, int up, int right, int down){
int widthNew = width+left+right;
int heightNew = height+up+down;
int[][][] rgbaArrayNew = new int[widthNew][heightNew][4];
if(left>0 || up>0 || right>0 || down>0){ // If increase the size, make the background transparent
int[] backgroundRGB = pickBackgroundRGB(0,0,width-1,height-1);
for (int line = 0; line < heightNew; line++) {
for (int column = 0; column < widthNew; column++) {
rgbaArrayNew[column][line][0] = backgroundRGB[0];
rgbaArrayNew[column][line][1] = backgroundRGB[1];
rgbaArrayNew[column][line][2] = backgroundRGB[2];
rgbaArrayNew[column][line][3] = 0;
}
}
}
for (int line = 0; line < (heightNew>height ? height : heightNew); line++) {
for (int column = 0; column < (widthNew>width ? width : widthNew); column++) {
for (int color = 0; color < 4; color++) {
int x = widthNew>width ? column : column-left;
int y = heightNew>height ? line : line-up;
int xNew = widthNew>width ? column+left : column;
int yNew = heightNew>height ? line+up : line;
rgbaArrayNew[xNew][yNew][color] = rgbaArray[x][y][color];
}
}
}
width = widthNew;
height = heightNew;
rgbaArray = rgbaArrayNew;
}
public void addSize(int fourDirections){
addSize(fourDirections,fourDirections,fourDirections,fourDirections);
}
}
Code:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author FL
**/
public class FormatImage {
public static void main(String[] args) {
copyImagesNumered(547,757,53);
}
/**
* Returns a list with names of all file at dir.
**/
public static ArrayList<String> fileNames(String dir){
ArrayList<String> ret = new ArrayList<String>();
File folder = new File(dir);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
ret.add(listOfFiles[i].getName());
// System.out.println("File " + listOfFiles[i].getName());
// } else if (listOfFiles[i].isDirectory()) {
// System.out.println("Directory " + listOfFiles[i].getName());
}
}
return ret;
}
/**
* Copy the numered image at Chaos Rush pack.
*
* @param firstIndex : Count as image index
* @param lastIndex : Count as image index
* @param correction : Difference between the pokémon index and the image number.
**/
public static void copyImagesNumered(int firstIndex, int lastIndex, int correction){
String dirOriginal="original";
String[] dir = new String[]{"front","frontshiny","back","backshiny"};
String[] name = new String[]{"","s","b","sb"};
String separatorDir = "/";
String separatorFile = ".";
String extension = "png";
List <Integer> femaleSpriteNames = Arrays.asList(new Integer[]{521,592,593});
Map <Integer,Integer> exceptions = new HashMap<Integer,Integer>();
int[] exceptioNames = null;
int exceptionFirstIndex = 736;
exceptioNames = new int[]{
550,555,585,585,585,586,586,586,646,646,648,649,649,649,649,641,642,645,647
};
for(Integer exception : exceptioNames){
exceptions.put(exceptionFirstIndex++,exception);
if(exceptionFirstIndex==750+1) // Small numeration fix
exceptionFirstIndex += 3;
}
//exceptions.put(exceptionFirstIndex++,550);
//exceptions.put(exceptionFirstIndex++,555);
int index = 0;
int formIndex = 0;
int lastForm = 0;
try {
index = firstIndex-correction;
while(index+correction<=lastIndex){
int originIndex = index+correction;
String originalLocation = dirOriginal+separatorDir+(originIndex)+separatorFile+extension;
ImageObject imageObject = ImageObject.factoryImageObject(originalLocation);
// imageObject.removeBackground();
imageObject.multiplySize(2);
String filename = index+"";
if(exceptions.containsKey(originIndex)){
int formName = exceptions.get(originIndex);
filename = formName+"";
formIndex = (formName == lastForm) ? formIndex+1 : 1;
lastForm = formName;
}else{
formIndex = 0;
}
boolean hadFemaleSprite = femaleSpriteNames.contains(index);
// Divides vertically the sprite if there two sprites for gender and add the "f" at the second sprite
ImageObject[] imageArrayGender = hadFemaleSprite ? imageObject.divide(2, false) : new ImageObject[]{imageObject};
boolean femaleSprite = false;
for(ImageObject imageObjectGender : imageArrayGender){
ImageObject[] imageObjectArray = imageObjectGender.divide(4, true);
for(int i=0;i<dir.length;i++){
String saveLocation = dir[i]+separatorDir+filename+(femaleSprite ? "f" : "")+name[i];
if(formIndex>0)
saveLocation+="_"+formIndex;
saveLocation+=separatorFile+extension;
imageObjectArray[i].removeBackground();
imageObjectArray[i].writeFile(saveLocation);
}
femaleSprite = true;
}
if(originIndex==750) // Small numeration fix
correction+=3;
if(originIndex==702) // Again
correction+=33;
if(formIndex==0){ // Doesn't has the exception number
index++;
}else{
correction++;
}
}
System.out.println("Success!");
} catch (IOException e) {
System.out.println("Failed at "+(index+correction)+"!");
e.printStackTrace();
}
}
}
Last edited: