ピクセル管理
画像からデータを処理する最も簡単な方法は、各ピクセルを取得し、そのチャネルの1つ以上の値を変更することです:赤、緑、青、およびアルファ(透明度)。簡潔にするために、R、G、B、およびAと呼びます。
例:値を変更します。たとえば、BとGを変更します。
rgb(100、50、30、255)はrgb(100、30、50、255)になりました
そのような操作は、単純なコールバック関数で表すことができます。 上記の例の場合:
function (r, g, b) { return [r, b, g, 255]; }
ここでは、アルファチャネルを無視します。これは必要ではなく、255に設定されます。
結果:
![画像](https://habrastorage.org/getpro/habr/post_images/576/ad7/874/576ad787459fb29dc1e73b8c85db9a38.jpg)
オリジナルから:
![画像](https://habrastorage.org/getpro/habr/post_images/dd3/bb2/d72/dd3bb2d7255af465e88212ffbb1d4faf.jpg)
アルファチャネルを変更し、イメージを部分的に透明にしたいとします。 次に、関数は次のようになります。
function (r, g, b, a, factor) { return [r, g, b, factor]; }
ここでは、ファクター変数を使用します。これにより、画像の透明度を設定します。 この変数の値は、アルファチャネルとして返されます。
![画像](https://habrastorage.org/getpro/habr/post_images/136/afc/f3c/136afcf3c8353acab45dca0b8ff49045.jpg)
より複雑な例。 ここで、透明度を適用する画像の部分を追加設定します。
function (r, g, b, a, factor, i) { var total = this.original.data.length; return [r, g, b, factor + 255 * (total - i) / total]; }
factor = 111にすると、次のようになります。
![画像](https://habrastorage.org/getpro/habr/post_images/51e/f9e/fea/51ef9efea146026a692c935b3d8135c0.jpg)
これは、私たちが作成した少し見えるオブジェクトを指します。 考慮された例として、それはそれ自体でいくつかの必要な情報を保存します。
キャンバス
キャンバスの構造を考慮してください。 コンストラクターから始めましょう。
function CanvasImage(canvas, src) { // var context = canvas.getContext('2d'); var i = new Image(); var that = this; i.onload = function(){ canvas.width = i.width; canvas.height = i.height; context.drawImage(i, 0, 0, i.width, i.height); // that.original = that.getData(); }; i.src = src; // this.context = context; this.image = i; }
これを使用して、画像のURLと同様に、ページ上のどこかにあるキャンバス要素へのリンクを渡します。
イメージは、データが処理されているのと同じドメインにある必要があります。
var transformador = new CanvasImage( $('canvas'), '/wp-content/uploads/2008/05/zlati-nathalie.jpg' );
コンストラクターは新しいImageオブジェクトを作成し、ロード後に画像がキャンバスに描画されます。 次に、コンテキスト、画像オブジェクト、元の画像データなど、将来のためにいくつかのものを保存します。 「これ」は、上記の例でピクセルマニピュレーターがアクセスできるものと同じです。
次に、キャンバスから画像データを設定、受信、ダンプするための3つの簡単な方法を使用します。
CanvasImage.prototype.getData = function() { return this.context.getImageData(0, 0, this.image.width, this.image.height); }; CanvasImage.prototype.setData = function(data) { return this.context.putImageData(data, 0, 0); }; CanvasImage.prototype.reset = function() { this.setData(this.original); }
すべての処理の頭脳は、transform()メソッドです。 これは、マニピュレーターのコールバック呼び出しをピクセルとファクターで処理します。これは、本質的にマニピュレーターの構成設定です。 次に、すべてのピクセルを通過し、rgbaチャネルのolddataの値をコールバック関数に渡し、返された値をnewdataとして使用します。 最後に、newdataがキャンバスに書き込まれます。
CanvasImage.prototype.transform = function(fn, factor) { var olddata = this.original; var oldpx = olddata.data; var newdata = this.context.createImageData(olddata); var newpx = newdata.data var res = []; var len = newpx.length; for (var i = 0; i < len; i += 4) { res = fn.call(this, oldpx[i], oldpx[i+1], oldpx[i+2], oldpx[i+3], factor, i); newpx[i] = res[0]; // r newpx[i+1] = res[1]; // g newpx[i+2] = res[2]; // b newpx[i+3] = res[3]; // a } this.setData(newdata); };
かなり簡単ですね。 恥ずかしい瞬間は、ループの増分i + = 4だけです。 データはgetImageData()を介して返され、各ピクセルに4つの要素を持つ配列としてのデータ。
画像に赤と青の2つのピクセルのみがあり、透明度がないとします。 この画像のデータは次のようになります。
[ 255, 0, 0, 255, 0, 0, 255, 255 ]
コールバック
次のコードは、コールバック関数のさまざまなオプションを単に示し、それらを使用するためのUIを作成します。 それらのいくつかを検討してください。
グレースケール
グレースケールは、赤、青、緑の等しい量です。 これを達成する最も簡単な方法は、平均値を計算することです:
var agv =(r + g + b)/ 3;
これで十分です。 しかし、人々と一緒に写真を処理するための秘密の公式があり、それはチャンネルに異なる感度を設定します
function(r, g, b) { var avg = 0.3 * r + 0.59 * g + 0.11 * b; return [avg, avg, avg, 255]; }
![画像](http://www.phpied.com/files/canvas/grey.jpg)
セピア
最も単純なオプション:グレーバージョンを作成し、少し色を追加します-各ピクセルに等しい量のrgb。 100個の赤、50個の緑を追加しましたが、他の値を選択できます。
function(r, g, b) { var avg = 0.3 * r + 0.59 * g + 0.11 * b; return [avg + 100, avg + 50, avg, 255]; }
![画像](http://www.phpied.com/files/canvas/sepia.jpg)
おそらくより良い別のオプションがありますが、私はそれがあまり好きではありません:
![画像](http://www.phpied.com/files/canvas/sepia2.jpg)
負
各チャネルの値を255から減算して、負の値を取得します
function(r, g, b) { return [255 - r, 255 - g, 255 - b, 255]; }
![画像](http://www.phpied.com/files/canvas/invert.jpg)
騒音
ノイズを追加します。 これは単なる娯楽であり、–factorとfactorの間のランダムな値を取得して、各チャネルに追加します。
function(r, g, b, a, factor) { var rand = (0.5 - Math.random()) * factor; return [r + rand, g + rand, b + rand, 255]; }
![画像](http://www.phpied.com/files/canvas/noise55.jpg)
あなたの動き
例自体は参照により公開されています 。 一部の操作では、ソースコードと想像力を使用して、独自に検討することができます。
テンプレートとして、次を実行します。
transformador.transform(function(r, g, b, a, factor, i) { // ... return [r, g, b, a]; });
たとえば、画像を白黒にしようとします(グレースケールではなく、各ピクセルが0,0,0または255,255,255のいずれかである白黒)。
または、あなたの興味深い例をいくつか考えてください。