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は、キャンバス上に描かれた色の情報をアラートダイアログに表示するプログラムです。
【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です。画像が表示されるまでに若干時間がかかりますが、画像の赤色が強調され表示されるはずです。
【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);
}
}
}