コード | nonameの雑記帳
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();
  }
}