2012/09/10更新

[HTML5] Canvasの表示内容にフィルターをかける(グレースケース、ネガポジ反転)

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
前回に引き続き今回は、HTML5 Canvasを用いた画像フィルターの第2弾として、 グレースケールとネガポジ反転のやり方をブログに書きたいと思います。

画像



Canvasで画像フィルターをかける

HTMl5 Canvasでは、表示してるビットマップデータにJavaScriptからアクセスすることが出来ます。
そのビットマップ値を変更することで、表示内容に画像フィルターなどの変化を与えることが出来ます。

画像フィルターシリーズのブログ記事では、その機能を用いて表示している画像にフィルターをかける方法を、 ライブラリなしに計算式や考え方を示しながら、実装内容を紹介しています。

以下は、画像フィルターシリーズの他のブログ記事です。参考になれば幸いです。
- HTML5 Canvasで表示内容にフィルターをかける(輝度)@YoheiM.NET



表示内容を白黒表示(グレースケール)にする

表示内容を白黒表示にするには、一つのピクセル上のR,G,Bの値を同一にすることで、 白/灰色/黒といった色味のないグレースケールにすることが出来ます。
R,G,Bのどの色の値に合わせても良いのですが、以下の式から算出される値を利用することで、 見慣れたグレースケールに出来るようです。
value = red * 0.2126 + green * 0.7152 + blue * 0.0722

上記の計算式を用いて、ビットマップのデータを変更するとグレースケールにすることが出来ます。
具体的な実装は以下の感じです。
// 対象のCanvasを取得し、contextも取得する。
var canvas  = document.querySelector("#myCanvas");
var context = canvas.getContext("2d");

// Canvasから描画内容を保持するimageDataを取得する。
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

// 描画内容に対して、上記のグレースケールにする式を当てはめながら
// rgbの値を計算する。
var d = imageData.data;
for (var i = 0; i < d.length; i+=4) {
     var g = d[i] * 0.2126 + d[i+1] * 0.7152 + d[i+2] * 0.0722;
     d[i] = d[i+1] = d[i+2] = g;
    // d[i+3]に格納されたα値は変更しない
}

// 計算結果でCanvasの表示内容を更新する。
context.putImageData(imageData, 0, 0);

上記の実装結果が以下のようになります。




ネガ反転のFilterを作成する

ネガ反転をするFilterの場合、白を黒、黒を白にするようにrgbの値を計算すればできます。
具体的には、以下のような計算を行います。
r = 255 - r;
g = 255 - g;
b = 255 - b;
上記の計算の場合、白(r,g,b=0,0,0)の場合は、黒(r,g,b=255,255,255)となります。

上記の計算式を用いて、ビットマップ値を計算する実装は以下となります。
// 対象のCanvasを取得し、contextも取得する。
var canvas  = document.querySelector("#myCanvas");
var context = canvas.getContext("2d");

// Canvasから描画内容を保持するimageDataを取得する。
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

// 描画内容に対して、上記のグレースケールにする式を当てはめながら
// rgbの値を計算する。
var d = imageData.data;
for (var i = 0; i < d.length; i+=4) {
    d[i] = 255 - d[i];
    d[i+1] = 255 - d[i+1];
    d[i+2] = 255 - d[i+2];
    // d[i+3]に格納されたα値は変更しない
}

// 計算結果でCanvasの表示内容を更新する。
context.putImageData(imageData, 0, 0);
上記の実装結果は、以下のように実行することが出来ます。




参考資料

画像Filterの考え方は、以下の資料を参考にしています。ありがとうございます(^ー^)ノ
- 画像処理におけるアルゴリズム



最後に

画像Filterって学んでみたいとずっと思ってたんです。その願いが少しかなって良かったです。
でも調べていくと、バリバリ数学なところも出てきて、数学をちゃんと学ばなきゃなぁと思う今日この頃。
図書館とかで数学の本を色々と借りて読もうと思ってます。

最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。