getImageDataによるCanvasの画像データ取得

CanvasにImageData形式の画像データを設定するputImageData()を使うと、JavaScriptで作成した配列の画像データ(フレームバッファ)を直接Canvasに描くことが出来ました。今回は、逆にCanvasに現在描かれている画像データをgetImageData()メソッドで取得し、JavaScriptでピクセルの色成分を書き換える「画像処理」を試してみましょう。

まず、Canvasの描画内容を格納したImageDataを取得するには、取得する範囲を指定してCanvasコンテキストのgetImageData(x, y, width, height)を呼び出します。Canvasコンテキストcontextから(0, 0)-(31, 31)の32*32ピクセルのImageDataを取得する場合なら

context.getImageData(0, 0, 32, 32)

のようにするわけです。

こうして取得したImageDataは、createImageDataで作成したものと同じくdataプロパティでピクセルの色情報を格納した配列にアクセスできるので、JavaScriptで画像処理を行った後にputImageData()でCanvasに描画することが出来ます。

試しに、putImageData()のテストで描いた32*32ピクセルの画像データをgetImageData()で取得、色情報を反転させて右下(32, 32の位置)に描いてみましょう。

<canvas id="test1" width="64" height="64"></canvas>

<script type="text/javascript">

	var cv = document.getElementById('test1');

	// Canvas要素とImageDataが実装されていれば処理続行
	if (cv.getContext && cv.getContext('2d').createImageData) {

		// Canvasのコンテキスト取得
		var context = cv.getContext('2d');

		// 32*32ピクセルのImageDataオブジェクト作成
		var imgData = context.createImageData(32, 32);

		// 各ピクセルの色情報設定
		for (i = 0;i < 32;i++) {
			for (j = 0;j < 32;j++) {

				// 赤成分
				imgData.data[j * 4 + i * imgData.width * 4] = j * 8;

				// 緑成分
				imgData.data[1 + j * 4 + i * imgData.width * 4] = 255 - (i * 8);

				// 青成分
				imgData.data[2 + j * 4 + i * imgData.width * 4] = i * 8;

				// アルファ成分
				imgData.data[3 + j * 4 + i * imgData.width * 4] = 255;

			}
		}

		// CanvasのコンテキストにImageDataを描画
		context.putImageData(imgData, 0, 0);

		// 現在のCanvas(0, 0)-(31, 31)の画像データを取得
		var imgData2 = context.getImageData(0, 0, 32, 32);

		// 各ピクセルの色情報設定(下位8ビット反転)
		for (i = 0;i < 32;i++) {
			for (j = 0;j < 32;j++) {

				// 赤成分
				imgData2.data[j * 4 + i * imgData2.width * 4] = imgData2.data[j * 4 + i * imgData.width * 4] ^ 0xff;

				// 緑成分
				imgData2.data[1 + j * 4 + i * imgData2.width * 4] = imgData2.data[1 + j * 4 + i * imgData.width * 4] ^ 0xff;

				// 青成分
				imgData2.data[2 + j * 4 + i * imgData2.width * 4] = imgData2.data[2 + j * 4 + i * imgData.width * 4] ^ 0xff;

			}
		}

		// Canvasのコンテキスト(32, 32)にImageData2を描画
		context.putImageData(imgData2, 32, 32);

	}

</script>

実行結果(CanvasやImageDataが未実装のWebブラウザでは表示されません)

前回のようなグラデーションが描画され、さらにその右下にJavaScriptの画像処理で作成された反転グラデーション(各色成分は0-255の範囲なので下位8ビットを反転させています)が表示されているはずです。

Canvasの画像データを取得できるようになれば、ユーザーの操作に応じて描画された内容を取得し画像処理を施してから再度表示、あるいはCanvasに読み込んだ画像データ(画像ファイル)に画像処理を行う、といったこともできるようになりますね。


創作プログラミングの街