日常の進捗

主に自分のための,行為とその習慣化の記録

Mod: Coding Challenge #47: Pixel Sorting in Processing

f:id:takawo:20171016114759j:plain

f:id:takawo:20171016114818j:plain

f:id:takawo:20171016114829j:plain

f:id:takawo:20171016102255j:plain

f:id:takawo:20171016102259j:plain

f:id:takawo:20171016115016j:plain

f:id:takawo:20171016120521j:plain

画像のピクセルごとのソーティング(並び替え).for文で順番にピクセルを見ていって,ピクセルの彩度(Hue)や明度(Brightness)を確認,その値が大きい場合に色を置き換える(スワップする).

スワップは2つの値を置き換えるやり方で,巡回セールスパーソン問題で都市の位置を入れ替えるときにもやっている.2つの値を入れ替えるのに以下の手順で行う.

  1. 変数Aと変数B以外に,もう一つ一時的な変数Cを用意
  2. 変数Cに変数Aの値を代入
  3. 変数Aに変数Bの値を代入
  4. 変数Bに変数C(つまりA)の値を代入

皿とか現実的なモノで考えるとわかりやすい.

書いたプログラムでは,上下もしくは左右で元画像とソートした画像を配置している.1ピクセルごとに走査しているので結構時間がかかる.画像はlorempixelsというフリーイメージを検索できるサイトのURLを指定しているので毎回ランダムに読み込まれてソートが終わったら画像保存するようにした.

lorempixel.com

関係ない話だけど,OpenProcessingだとhue(color c)とか色取得系の関数が実行できないのは謎.Processing.jsだと動くはずなのだけど.

コード

PImage img, imgSorted;
int nTimes = 10;
int pxIndex;

void setup() {
  //fullScreen();
  size(850, 450); 
  colorMode(HSB, 360, 100, 100); 
  init();
}

void init() {
  String str = new String();
  if (random(1) < 0.5) {
    str = "http://lorempixel.com/" + width/2 +"/"+ height + "/";
  } else {
    str = "http://lorempixel.com/" + width +"/"+ height/2 + "/";
  }

  img = loadImage(str, "jpg");
  imgSorted = img.get();
  pxIndex = 0;
}

// draw関数 : setup関数実行後繰り返し実行される
void draw() {
  if (img != null) {
    image(img, 0, 0);
  }

  imgSorted.loadPixels();

  for (int n = 0; n < nTimes; n++) {
    float record = -1;
    int pxSelected = pxIndex;
    for (int i = pxIndex; i < imgSorted.pixels.length; i++) {
      color pxColor = imgSorted.pixels[i];
      float hue = hue(pxColor);
      if (hue > record) {
        pxSelected = i;
        record = hue;
      }
    }
    colorSwap(imgSorted, pxIndex, pxSelected);
    if (pxIndex < imgSorted.pixels.length -1) {
      pxIndex++;
    } else {
      saveFrame(dataPath("") + "/" + width + "_"+ height + "_" + "######.jpg");
      pxIndex = 0;
      init();
    }
  }
  imgSorted.updatePixels();
  background(0, 0, 0);
  if (img.width > width/2) {
    image(img, 0, 0);
    image(imgSorted, 0, height/2);
  } else {
    image(img, 0, 0);
    image(imgSorted, width/2, 0);
  }
}

void colorSwap(PImage image, int i, int j) {
  color temp = image.pixels[i];
  image.pixels[i] = image.pixels[j];
  image.pixels[j] = temp;
}

void mousePressed() {
  init();
}

リファレンス