import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.PrintWriter;

import java.io.UnsupportedEncodingException;

import java.nio.file.Files;

import java.nio.file.Paths;


import javax.imageio.ImageIO;


public class Main {

public static void main(String[] args){

RunningStructure r = new RunningStructure();

}

}


class RunningStructure{

final int THREADNAME=0, COLORHEX=1;

final int RED=0, GREEN=1, BLUE=2;

String threadlist = "";

public RunningStructure(){

String csvInput = getFile(System.getProperty("user.dir") + File.separator + "dmc.csv");//CSV file input

String[][] csv = getCSV(csvInput);

BufferedImage image = getImage(System.getProperty("user.dir") + File.separator + "input.jpg");//Image file input

int[][] pixelArray = getPixelArray(image);//get Pixel array

int width = pixelArray.length;

int height = pixelArray[0].length;

for(int i=0; i<width; i++){

for(int j=0; j<height; j++){

image.setRGB(i, j, getMinColor(csv, String.format("X", (0xFFFFFF & pixelArray[i][j]), 16)));//compare color and replace

}

}

writeImage(image, "output.png");

writeColorList(threadlist);//output image and threadlist

System.out.println("output completed.");

}

String getFile(String dir){

try {

return new String(Files.readAllBytes(Paths.get(dir)));

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

BufferedImage getImage(String dir){

try {

return ImageIO.read(new File(dir));

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

void writeImage(BufferedImage image, String filename){

File outputfile = new File(filename);

try {

ImageIO.write(image, "png", outputfile);

} catch (IOException e) {

e.printStackTrace();

}

}

void writeColorList(String str){

PrintWriter writer;

try {

writer = new PrintWriter("color.txt", "UTF-8");

writer.print(str);

writer.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

}

int[][] getPixelArray(BufferedImage image){

int w=image.getWidth(), h=image.getHeight();

int[][] pixels = new int[w][h];

for(int i=0; i<w; i++){

for(int j=0; j<h; j++){

pixels[i][j] = image.getRGB(i, j);

}

}

return pixels;

}

String[][] getCSV(String str){

String[] split1 = str.split("\r\n");

String[][] output = new String[split1.length][2];

for(int i=0; i<split1.length; i++){

String[] split2 = split1[i].split(",");

output[i][THREADNAME] = split2[THREADNAME];

output[i][COLORHEX] = split2[COLORHEX];

}

return output;

}

int hexToColor(String str, int mode){

String s = "";

switch(mode){

case RED:

s = str.substring(0, 2);

break;

case GREEN:

s = str.substring(2, 4);

break;

case BLUE:

s = str.substring(4, 6);

break;

}

return Integer.decode("0x" + s);

}

int getMinColor(String[][] csv, String targetColor){

int difference = 255*3;

String colorName = "", colorHex = "";

int calculatedDifference = 0;

int maxlength = csv.length;

for(int i=0; i<maxlength; i++){

calculatedDifference = calculateDifference(csv[i][COLORHEX], targetColor);

if(calculatedDifference<difference){

colorName = csv[i][THREADNAME];

colorHex = csv[i][COLORHEX];

difference = calculatedDifference;

}

}

addColor(colorName);

return Integer.parseInt(colorHex, 16);

}

boolean addColor(String color){

if(!threadlist.matches("")){

String[] split = threadlist.split("\r\n");

for(int i=0; i<split.length; i++){

if(split[i].matches(color))

return false;

}

}

threadlist += color + "\r\n";

return true;

}

int calculateDifference(String originalHeximal, String targetColor){

int or = hexToColor(originalHeximal, RED);

int og = hexToColor(originalHeximal, GREEN);

int ob = hexToColor(originalHeximal, BLUE);

int tr = hexToColor(targetColor, RED);

int tg = hexToColor(targetColor, GREEN);

int tb = hexToColor(targetColor, BLUE);

return Math.abs(or-tr)+Math.abs(og-tg)+Math.abs(ob-tb);

}

}


일반 이미지를 십자수용 색상이 사용된 이미지로 변환하는 툴인데요


일단 프로그램이 이미지를 입력받고 십자수용 색 리스트가 있는 csv파일을 입력받으면

픽셀 전체를 for문으로 돌면서 해당 rgb값과 csv 전체에 있는 색값을 비교해서(해당 픽셀과 csv에 있는 색의 차이를 계산하는 함수는 calculateDifference)

그 픽셀의 rgb값과 가장 차이가 적게 나는 csv 색을 찾아서 해당 픽셀을 대체하는 작업인데요(int getMinColor함수, return값은 가장 차이가 적은 csv에 있는 색)

bmp, jpg포맷 파일을 시도했을 때에는 정상적으로 변환완료가 되는데 png에 알파 채널이 있는 경우에는 출력파일이 전부 검은색으로 나옵니다...

csv 형식은
310,000000
823,000b44
311,002a64
3818,005d2e
995,0061b0
943,009a77
3808,03535c

이런식으로 앞이 색이름 뒤가 16진수 색코드로 되어있어요