Mod: Coding Challenge #47: Pixel Sorting in Processing
画像のピクセルごとのソーティング(並び替え).for文で順番にピクセルを見ていって,ピクセルの彩度(Hue)や明度(Brightness)を確認,その値が大きい場合に色を置き換える(スワップする).
スワップは2つの値を置き換えるやり方で,巡回セールスパーソン問題で都市の位置を入れ替えるときにもやっている.2つの値を入れ替えるのに以下の手順で行う.
- 変数Aと変数B以外に,もう一つ一時的な変数Cを用意
- 変数Cに変数Aの値を代入
- 変数Aに変数Bの値を代入
- 変数Bに変数C(つまりA)の値を代入
皿とか現実的なモノで考えるとわかりやすい.
書いたプログラムでは,上下もしくは左右で元画像とソートした画像を配置している.1ピクセルごとに走査しているので結構時間がかかる.画像はlorempixelsというフリーイメージを検索できるサイトのURLを指定しているので毎回ランダムに読み込まれてソートが終わったら画像保存するようにした.
関係ない話だけど,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(); }