PImage img0;
PImage writeImg;
//Window Size
final int size_x = 32;
final int size_y = 32;
final int dotframe = 1;
final int scale = 24;
final int n_pallet = 159;
final int max_color = 15;
final int font_size = int(scale/2);
float [] pallet_r = {
255, 255, 239, 255, 255, 189, 206, 156, 82,
255, 255, 222, 255, 255, 206, 189, 189, 140,
222, 255, 222, 255, 255, 189, 222, 189, 99,
255, 255, 255, 255, 255, 222, 189, 156, 140,
255, 239, 206, 189, 206, 156, 140, 82, 49,
255, 255, 222, 255, 255, 140, 189, 140, 82,
222, 206, 115, 173, 156, 115, 82, 49, 33,
255, 255, 222, 255, 255, 206, 156, 140, 82,
222, 189, 99, 156, 99, 82, 66, 33, 33,
189, 140, 49, 49, 0, 49, 0, 16, 0,
156, 99, 33, 66, 0, 82, 33, 16, 0,
222, 206, 140, 173, 140, 173, 99, 82, 49,
189, 115, 49, 99, 16, 66, 33, 0, 0,
173, 82, 0, 82, 0, 66, 0, 0, 0,
206, 173, 49, 82, 0, 115, 0, 0, 0,
173, 115, 99, 0, 33, 82, 0, 0, 33,
255, 239, 222, 206, 189,
173, 156, 140, 115, 99,
82, 66, 49, 33, 0
};
float [] pallet_g = {
239, 154, 85, 101, 0, 69, 0, 0, 32,
186, 117, 48, 85, 0, 101, 69, 0, 32,
207, 207, 101, 170, 101, 138, 69, 69, 48,
239, 223, 207, 186, 170, 138, 101, 85, 69,
207, 138, 101, 138, 0, 101, 0, 0, 0,
186, 154, 32, 85, 0, 85, 0, 0, 0,
186, 170, 69, 117, 48, 48, 32, 16, 16,
255, 255, 223, 255, 223, 170, 154, 117, 85,
186, 154, 48, 85, 0, 69, 0, 0, 16,
186, 154, 48, 85, 0, 48, 0, 16, 0,
239, 207, 101, 170, 138, 117, 85, 48, 32,
255, 255, 170, 223, 255, 186, 186, 154, 101,
223, 207, 85, 154, 117, 117, 69, 32, 16,
255, 255, 138, 186, 207, 154, 101, 69, 32,
255, 239, 207, 239, 255, 170, 170, 138, 69,
255, 255, 223, 255, 223, 186, 186, 138, 69,
255, 239, 223, 207, 186,
170, 154, 138, 117, 101,
85, 69, 48, 32, 0
};
float [] pallet_b = {
255, 173, 156, 173, 99, 115, 82, 49, 49,
206, 115, 16, 66, 0, 99, 66, 0, 33,
189, 99, 33, 33, 0, 82, 0, 0, 16,
222, 206, 173, 140, 140, 99, 66, 49, 33,
255, 255, 222, 206, 255, 156, 173, 115, 66,
255, 255, 189, 239, 206, 115, 156, 99, 66,
156, 115, 49, 66, 0, 33, 0, 0, 0,
206, 115, 33, 0, 0, 0, 0, 0, 0,
255, 239, 206, 255, 255, 140, 156, 99, 49,
255, 255, 173, 239, 255, 140, 173, 99, 33,
189, 115, 16, 49, 49, 82, 0, 33, 16,
189, 140, 82, 140, 0, 156, 0, 0, 0,
255, 255, 156, 255, 255, 173, 115, 115, 66,
255, 255, 189, 206, 255, 173, 140, 82, 49,
239, 222, 173, 189, 206, 173, 156, 115, 49,
173, 115, 66, 0, 33, 82, 0, 0, 33,
255, 239, 222, 206, 189,
173, 156, 140, 115, 99,
82, 66, 49, 33, 0
};
void setup() {
size(size_x*scale*2+dotframe, size_y*scale);
println("select photo.");
String imgPath = selectInput();
img0 = loadImage(imgPath);
textSize(font_size);
background(0,0,0);
writeImg = createGraphics(size_x*scale, size_y*scale, P2D);
}
int CountColor(int[] pallet, int n) {
int cont = 0;
int []pallet_cnt = new int[n];
for (int i=0; i < n; i++) {
pallet_cnt[i] = 0;
for (int j= 0; j < size_x*size_y; j++) {
if (pallet[j] == i) {
pallet_cnt[i]++;
}
}
}
for (int i=0; i < n; i++) {
if (pallet_cnt[i] > 0) {
cont++;
}
}
return cont;
}
void draw() {
img0.loadPixels();
// Making Image-----
float[] img_r = new float[img0.width*img0.height];
float[] img_g = new float[img0.width*img0.height];
float[] img_b = new float[img0.width*img0.height];
float[] img16_r = new float[size_x*size_y];
float[] img16_g = new float[size_x*size_y];
float[] img16_b = new float[size_x*size_y];
int[] img16_pallet = new int[size_x*size_y];
for (int i = 0; i < img0.width*img0.height; i++) {
color tmp_color = img0.pixels[i];
img_r[i] = red(tmp_color);
img_g[i] = green(tmp_color);
img_b[i] = blue(tmp_color);
}
int div_x = int(img0.width / size_x);
int div_y = int(img0.height / size_y);
float tmp_r;
float tmp_g;
float tmp_b;
// make dot image
for (int i = 0; i < size_x*size_y; i++) {
tmp_r = 0;
tmp_g = 0;
tmp_b = 0;
int tmp_y = int(i / size_x);
int tmp_x = i - size_x*tmp_y;
for (int j = 0; j < div_x; j++) {
for (int k = 0; k < div_y; k++) {
tmp_r += img_r[tmp_x*div_x + tmp_y*img0.width*div_y+ j + k*img0.width];
tmp_g += img_g[tmp_x*div_x + tmp_y*img0.width*div_y+ j + k*img0.width];
tmp_b += img_b[tmp_x*div_x + tmp_y*img0.width*div_y+ j + k*img0.width];
}
}
tmp_r = tmp_r/(div_x*div_y);
tmp_g = tmp_g/(div_x*div_y);
tmp_b = tmp_b/(div_x*div_y);
img16_r[i] = tmp_r;
img16_g[i] = tmp_g;
img16_b[i] = tmp_b;
}
writeImg.loadPixels();
// matching pallet
for (int i = 0; i < size_x*size_y; i++) {
float []tmp_color_distance = new float[n_pallet];
for (int j= 0; j < n_pallet; j++) {
tmp_color_distance[j] =
(img16_r[i] - pallet_r[j])*(img16_r[i] - pallet_r[j]) +
(img16_g[i] - pallet_g[j])*(img16_g[i] - pallet_g[j]) +
(img16_b[i] - pallet_b[j])*(img16_b[i] - pallet_b[j]);
}
float tmp_color_min = tmp_color_distance[0];
img16_pallet[i] = 0;
for (int j= 1; j < n_pallet; j++) {
if (tmp_color_min > tmp_color_distance[j]) {
tmp_color_min = tmp_color_distance[j];
img16_pallet[i] = j;
}
}
}
// reduce pallet
while (CountColor (img16_pallet, n_pallet) > max_color) {
int []pallet_cnt = new int[n_pallet];
for (int i=0; i < n_pallet; i++) {
pallet_cnt[i] = 0;
for (int j= 0; j < size_x*size_y; j++) {
if (img16_pallet[j] == i) {
pallet_cnt[i]++;
}
}
}
int min_colornumb = 0;
int first_cnt=0;
int min_tmp = 0;
while (pallet_cnt[first_cnt] == 0) {
first_cnt++;
}
int min_colorcnt = pallet_cnt[first_cnt];
for (int i=first_cnt; i < n_pallet; i++) {
if (min_colorcnt > pallet_cnt[i] && pallet_cnt[i] > 0) {
min_tmp = 1;
min_colorcnt = pallet_cnt[i];
min_colornumb = i;
}
}
float min_colordist = 0;
int neardist_colornumb = 0;
if (min_tmp == 0) {
min_colornumb = first_cnt;
int tmp_cnt = first_cnt+1;
while (pallet_cnt[tmp_cnt] == 0) {
tmp_cnt++;
}
min_colordist =
(pallet_r[min_colornumb]-pallet_r[tmp_cnt])*(pallet_r[min_colornumb]-pallet_r[tmp_cnt])
+ (pallet_g[min_colornumb]-pallet_g[tmp_cnt])*(pallet_g[min_colornumb]-pallet_g[tmp_cnt])
+ (pallet_b[min_colornumb]-pallet_b[tmp_cnt])*(pallet_b[min_colornumb]-pallet_b[tmp_cnt]);
neardist_colornumb = tmp_cnt;
}
else {
min_colordist =
(pallet_r[min_colornumb]-pallet_r[first_cnt])*(pallet_r[min_colornumb]-pallet_r[first_cnt])
+ (pallet_g[min_colornumb]-pallet_g[first_cnt])*(pallet_g[min_colornumb]-pallet_g[first_cnt])
+ (pallet_b[min_colornumb]-pallet_b[first_cnt])*(pallet_b[min_colornumb]-pallet_b[first_cnt]);
neardist_colornumb = first_cnt;
}
for (int i=first_cnt; i < n_pallet; i++) {
if (pallet_cnt[i] > 0 && i != min_colornumb) {
float tmp_dist =
(pallet_r[min_colornumb]-pallet_r[i])*(pallet_r[min_colornumb]-pallet_r[i])
+ (pallet_g[min_colornumb]-pallet_g[i])*(pallet_g[min_colornumb]-pallet_g[i])
+ (pallet_b[min_colornumb]-pallet_b[i])*(pallet_b[min_colornumb]-pallet_b[i]);
if (min_colordist > tmp_dist) {
min_colordist = tmp_dist;
neardist_colornumb = i;
}
}
}
for (int i=0; i < size_x*size_y; i++) {
if (img16_pallet[i] == min_colornumb) {
img16_pallet[i] = neardist_colornumb;
}
}
}
// pallet update
for (int i = 0; i < size_x*size_y; i++) {
img16_r[i] = pallet_r[img16_pallet[i]];
img16_g[i] = pallet_g[img16_pallet[i]];
img16_b[i] = pallet_b[img16_pallet[i]];
}
// scaling dot image
for (int i = 0; i < size_x*size_y; i++) {
int tmp_y = int(i / size_x);
int tmp_x = i - size_x*tmp_y;
for (int j = 0; j < scale; j++) {
for (int k = 0; k < scale; k++) {
writeImg.pixels[tmp_y*size_x*scale*scale+tmp_x*scale+j*size_x*scale+k] = color(img16_r[i], img16_g[i], img16_b[i]);
}
}
}
writeImg.updatePixels();
image(writeImg, 0, 0, size_x*scale, size_y*scale);
// draw pallet number
for (int x = 0; x < size_x; x++) {
for (int y = 0; y < size_y; y++) {
String tx = str(img16_pallet[y*size_x+x]);
fill(255,255,255);
textAlign(CENTER);
text(tx, size_x*scale+(x+0.5)*scale, (y+0.5)*scale);
}
}
// draw frame
for (int x = 0; x < size_x*2+1; x++) {
stroke(255);
strokeWeight(dotframe);
line(x*scale, 0, x*scale, size_y*scale);
}
for (int y = 0; y < size_y+1; y++) {
stroke(255);
strokeWeight(dotframe);
line(0, y*scale-dotframe, size_x*scale*2+1, y*scale-dotframe);
}
}
void keyPressed() {
// save image
if (key == 'p' || key == 'P') {
save("screenshot.jpg");
println("screen saved.");
}
// exit
if (key == ' ') {
exit();
}
}