このページの本文へ

HTML5のcanvasで作る画像フィルター (2/6)

2009年10月07日 10時00分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

Opera編:
ピクセル単位の読み書きができるgetPixel()/setPixel

 canvasはほとんどのブラウザーに実装されていますが、ブラウザーによって実装内容にかなりの違いがあります。まずは、もっとも早くからピクセル単位の画像処理をサポートしている「Opera」から取り掛かりましょう。Operaには、ピクセル単位の読み書きに対応するgetPixel()/setPixel()メソッドが用意されており、使い方は非常に簡単です。

 canvasで画像を描画するために、まずgetContext()メソッドで描画用のコンテキストを取得します。通常は、


var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");


 のようにgetContext()の引数に"2d"を指定しますが(2dは2次元=平面の意味)、Operaでピクセル処理をする場合は"opera-2dgame"を指定します。


var gContext = canvas.getContext("opera-2dgame");


 描画コンテキストを取得すれば、以下のようにgetPixel()、setPixel()が使えるようになります。


rgba = gContext.getPixel(20,20);    
gContext.setPixel(x,y, rgbaColor);


 getPixel()には、(1)キャンバス上のX座標、(2)Y座標、の2つの引数を指定します。たとえば、getPixel(10, 30) なら座標(10, 30)にあるピクセルの色を取得できます。ピクセルの色は以下のように、#で始まる文字列で返されますので、文字列を分解して必要な色の値を取り出します。

#RRGGBB

RR : 赤の輝度(16進数2桁)
GG : 緑の輝度(16進数2桁)
BB : 青の輝度(16進数2桁)


 サンプル1は、キャンバス上に描かれた色の情報をアラートダイアログに表示するプログラムです。

fig2-1.png

ピクセルの色情報がダイアログに表示される


●サンプル1(Opera 9.0以降専用)

【HTML】


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
        <title>Sample</title>
        <link rel="stylesheet" href="css/main.css" type="text/css" media="all">
        <script type="text/javascript" src="js/sample.js"></script>
    </head>
    <body>
        <h1>Operaでキャンバス上のピクセル値を取得する</h1>
        <canvas id="myCanvas" width="640" height="480">canvasに対応したブラウザーで実行してください</canvas>
    </body>
</html>


【sample.js】


window.onload = function(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
    context.fillStyle = "rgba(0,0,255,1)";  // 青色にする
    context.fillRect(0,0,320,240);  // 塗りつぶす
    var gContext = canvas.getContext("opera-2dgame");
    var rgba = gContext.getPixel(20,20);    // ピクセル値を取得する
    alert(rgba);
}


 キャンバス上に任意の色のピクセルを描画するのは、setPixel()メソッドを使います。引数は、(1)描画したいキャンバス上のX座標、(2)Y座標、(3)描画する色、の3つで、(3)の色は以下の形式の文字列で指定します。


rgba(赤の輝度,緑の輝度,青の輝度,不透明度)


 輝度は0がもっとも暗く、255がもっとも明るくなります。不透明度は0~1.0までの小数値で指定し、0が完全な透明、1.0が完全な不透明です。


■Opera専用赤色強調フィルターを作る

 ピクセル単位の読み書きの方法が分かったところで、実際にOpera用の赤色強調フィルターを作成してみましょう。

 まず、フィルター処理の対象となる画像を読み込ませます。画像の読み込みは、new Image()で画像の横幅と縦幅を、srcプロパティに表示したい画像のファイル名(URL)を指定します。後述するFirefoxの場合は、画像を同一ドメインに置き、http://~から始まるURLを絶対パスで指定する必要がありますが、Operaには特にそういった制限はありませんので、ファイル名のみの記述でかまいません。描画する画像オブジェクトと、表示するXY座標はdrawImage()で指定します。


var _canvasW = 300;   // 横幅300ピクセル
var _canvasH = 169;   // 縦幅169ピクセル
var imgObj = new Image(_canvasW, _canvasH);
imgObj.src = "asama.jpg";
context.drawImage(imgObj, 0, 0);


 実際のプログラムはサンプル2です。画像が表示されるまでに若干時間がかかりますが、画像の赤色が強調され表示されるはずです。

fig2-2.png

画像が読み込まれ赤色が強調された状態で描画される


●サンプル2(Opera 9.0以降専用)

【HTML】


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
        <title>Sample</title>
        <link rel="stylesheet" href="css/main.css" type="text/css" media="all">
        <script type="text/javascript" src="js/sample.js"></script>
    </head>
    <body>
        <h1>Operaでフィルター処理</h1>
        <canvas id="myCanvas" width="300" height="169">canvasに対応したブラウザーで実行してください</canvas>
    </body>
</html>


【sample.js】


window.onload = function(){
    var _canvasW = 300;   // 横幅300ピクセル
    var _canvasH = 169;   // 縦幅169ピクセル
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
    var imgObj = new Image(_canvasW, _canvasH);
    imgObj.src = "asama.jpg";
    context.drawImage(imgObj, 0, 0);
    var gContext = canvas.getContext("opera-2dgame");
    // フィルター処理
    for(var y=0; y<_canvasH; y++){
        for(var x=0; x<_canvasW; x++){
            var rgbStr = gContext.getPixel(x, y); // ピクセル値を取得する
            var R = eval("0x"+rgbStr.substring(1,3));
            var G = eval("0x"+rgbStr.substring(3,5));
            var B = eval("0x"+rgbStr.substring(5,7));
            R = R  * 2;
            if (R > 255) R = 255;
            G = Math.floor(G / 2);
            B = Math.floor(B / 2);
            var rgbaColor = "rgba("+R+","+G+","+B+", 1.0)";
            gContext.setPixel(x,y, rgbaColor);
        }
    }
}


この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています