ハーフトーニング(拡散誤差法)
パターンを用いたものではなく、空間フィルタリングのときのようなフィルタを掛けて2値化。
コード
ImageProcessing.prototype.errorDiffuse = function(flt){ var self = this; // init var w = this.canvas.width; var h = this.canvas.height; var sum = 0; // total of flt values var tmp = []; // temporary colors var fw = flt[0].length; // filter width var cur = parseInt(fw / 2, 10); // current pixel (X) of flt // init sum flt.forEach(function(_){ _.forEach(function(n){ sum += n; }); }); // init tmp for(var y = 0; y < h; y++){ tmp[y] = []; for(var x = 0; x < w; x++){ tmp[y][x] = 0; } } // filtering this.each(function(px, x, y){ var e; var f = tmp[y][x] + px.average(); if(f > 127){ tmp[y][x] = 255; e = f - 255; } else{ tmp[y][x] = 0; e = f; } flt.forEach(function(_, ny){ var _y = y + ny; if(_y >= h) return; _.forEach(function(v, nx){ var _x = x + nx - cur; if(0 > _x || _x >= w || !flt[ny][nx]) return; tmp[_y][_x] += e * v / sum; }); }); }); tmp.forEach(function(_, y){ _.forEach(function(v, x){ self.setPixel(x, y, new ImageProcessing.Color(v, v, v)); }); }); }
- フィルタ
フィルタは空間フィルタリングと似ているけど、下半分だけ定義する。
p-1.0 | p0,0 | p+1,0 |
---|---|---|
p-1.+1 | p0,+1 | p+1,+1 |
(それぞれを値の合計で割る)
- 参考(フィルタがいっぱい載ってる)
その他
http://arikui.s101.xrea.com/test/canvas/cg/test/error_diffusion.html
今回はFirefoxでもできます。Operaよりは遅いです。
Firefox対応
http://github.com/arikui/image_processing.js/tree/master
opera-2dgameが使えない場合は、ImageDataを使ってgetPixel/setPixelをするようにした。単純に1ピクセルずつ黒く塗りつぶす処理で、ImageDataの方は2倍近く遅かった。ImageDataの方は指定した範囲のデータを一気に取得できるので、使いようでは速くなるのかもしれない。