Javascriptを使用してキャンバス上のピクセルを操作する

この記事では、JavascriptとHTMLキャンバスタグを使用した画像管理について説明します。 この記事は翻訳です。 phpied.comのオリジナル



ピクセル管理



画像からデータを処理する最も簡単な方法は、各ピクセルを取得し、そのチャネルの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に設定されます。



結果:



画像



オリジナルから:



画像



アルファチャネルを変更し、イメージを部分的に透明にしたいとします。 次に、関数は次のようになります。



 function (r, g, b, a, factor) { return [r, g, b, factor]; }
      
      







ここでは、ファクター変数を使用します。これにより、画像の透明度を設定します。 この変数の値は、アルファチャネルとして返されます。



画像



より複雑な例。 ここで、透明度を適用する画像の部分を追加設定します。



 function (r, g, b, a, factor, i) { var total = this.original.data.length; return [r, g, b, factor + 255 * (total - i) / total]; }
      
      







factor = 111にすると、次のようになります。



画像

これは、私たちが作成した少し見えるオブジェクトを指します。 考慮された例として、それはそれ自体でいくつかの必要な情報を保存します。



キャンバス



キャンバスの構造を考慮してください。 コンストラクターから始めましょう。



 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]; }
      
      







画像



セピア


最も単純なオプション:グレーバージョンを作成し、少し色を追加します-各ピクセルに等しい量の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]; }
      
      







画像



おそらくより良い別のオプションがありますが、私はそれがあまり好きではありません:



画像





各チャネルの値を255から減算して、負の値を取得します



 function(r, g, b) { return [255 - r, 255 - g, 255 - b, 255]; }
      
      







画像



騒音


ノイズを追加します。 これは単なる娯楽であり、–factorとfactorの間のランダムな値を取得して、各チャネルに追加します。

 function(r, g, b, a, factor) { var rand = (0.5 - Math.random()) * factor; return [r + rand, g + rand, b + rand, 255]; }
      
      





画像



あなたの動き



例自体は参照により公開されています 。 一部の操作では、ソースコードと想像力を使用して、独自に検討することができます。

テンプレートとして、次を実行します。



 transformador.transform(function(r, g, b, a, factor, i) { //   ... return [r, g, b, a]; });
      
      







たとえば、画像を白黒にしようとします(グレースケールではなく、各ピクセルが0,0,0または255,255,255のいずれかである白黒)。



または、あなたの興味深い例をいくつか考えてください。



All Articles