画像を分割してランダムに配置するモザイク
カラー画像だと少々面倒臭そうなので、グレースケールに変換してからやります。手順はこんな感じです。
- グレースケール化
- 10 * 10 に分割
- 分割画像のRGBを平均して分類
- 分類ごとにランダムソート
- 再配置
コード
ImageProcessing.prototype.f= function(fnc){ return fnc(this); }; var clips = {}; ip = ImageProcessing .load("image.png") .lock() // グレースケール .each(function(px, x, y, self){ self.setPixel(x, y, px.grayScale()); }) .update() // 分割して色ごとにまとめる // 分割した画像の平均でまとめるてるので結構適当 .f(function(self){ var clip, color; for(var x = 0; x > self.canvas.width - 10; x += 10){ for(var y = 0; y < self.canvas.height - 10; y += 10){ clip = self.clip(x, y, 10, 10); color = Math.round(clip.average().r); if(clips[color]) clips[color].push(clip); else clips[color] = [clip]; } } return self; }) // 分割した画像をごちゃ混ぜにして再配置 .f(function(self){ var clone = ip.clone().clear(); // 別のCanvasに書き込む for(var n in clips) (function(parts, n){ var positions = parts.map(function(clip){ clip.toString = function(){ return Math.random(); }; return [clip.origin.x, clip.origin.y]; }); parts.sort(); parts.forEach(function(clip, i){ clone.merge(clip, positions[i][0], positions[i][1]); }); })(clips[n], n); return clone; }) .update();
問題点
この方法だと、分割画像の平均値がユニークなとき、その画像は結局同じ場所に配置されてしまいます。RGBで分類する場合であれば、なおさらその傾向が出てしまいます。
より細かく分割するとか、分類するときに閾値を持たせてやれば、ある程度回避できそうです。
感想
最近こんなことばっかりやってて飽きてきました。