このページの本文へ

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

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

文●古籏一浩

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

共通で使えるピクセル処理関数を作る

 HTML5の仕様が決定していないので仕方がないのですが、ブラウザーによって処理を変更するのは面倒です。ピクセル単位での処理は同じプログラムでできると思っていましたが、実際にやってみると結構な手間がかかりました。OperaがFirefoxなど他のブラウザーと同じメソッドを実装すればプログラムは簡単になりますが、ピクセル単位で処理したい場合はsetPixel()、getPixel()の方が手軽ではないかと思います。

 そこで最後に、どのブラウザーでも使用できるgetPixel()/setPixel()メソッドを作成しましょう。getPixel()は、Operaの場合だけ処理を分岐し、もともと用意されているgetPixel()メソッドを使ってピクセル値を読み出します。ブラウザーがOperaかどうかは、windowオブジェクトのoperaプロパティの有無で判断できます。


if (window.opera) { Operaの場合の処理 }


 Firefox/Safari/Google Chromeの場合はgetImageData()を利用してピクセル値を読み出します。ピクセル値の書き込みはOperaではsetPixel()、Firefox/Safari/Google ChromeはputImageData()を利用します。

 実際のプログラムはサンプル5にまとめました。ピクセル単位での処理なので表示までには多少時間がかかります。

fig-5

どのブラウザーでも同じプログラムでフィルター処理ができる


●サンプル5

【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>ブラウザーでフィルター処理</h1>
        <img src="asama.jpg" style="display: none"><br>
        <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 = "http://■■■■/●●●●/asama.jpg";
    context.drawImage(imgObj, 0, 0);
    // フィルター処理
    for(var y=0; y<_canvasH; y++){
        for(var x=0; x<_canvasW; x++){
            var pixelData = getPixel(canvas, x, y, _canvasW, _canvasW);   // ピクセル値を取得する
            var R = pixelData.R;
            var G = pixelData.G;
            var B = pixelData.B;
            R = R  * 2;
            if (R > 255) R = 255;
            G = Math.floor(G / 2);
            B = Math.floor(B / 2);
            setPixel(canvas, x, y, R, G, B, 255, _canvasW, _canvasW);
        }
    }
}
// GetPixel
// 戻り値はオブジェクトのプロパティでR,G,B
function getPixel(srcCanvas, x, y, canvasW, canvasH){
    if (window.opera) {
        var gContext = srcCanvas.getContext("opera-2dgame");
        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));
        return {R:R, G:G, B:B};
    }
    var imagePixelData = srcCanvas.getContext("2d").getImageData(x, y, 1, 1).data;
    var R = imagePixelData[0];
    var G = imagePixelData[1];
    var B = imagePixelData[2];
    return {R:R, G:G, B:B};
}
// SetPixel
function setPixel(srcCanvas, x, y, R, G, B, A, canvasW, canvasH){
    if (window.opera) {
        var gContext = srcCanvas.getContext("opera-2dgame");
        var rgbaColor = "rgba("+R+","+G+","+B+","+A+")";
        gContext.setPixel(x,y, rgbaColor);
        return;
    }
    var context = srcCanvas.getContext("2d");
    var pixelImage = context.createImageData(1, 1);
    pixelImage.data[0] = R;
    pixelImage.data[1] = G;
    pixelImage.data[2] = B;
    pixelImage.data[3] = A;
    context.putImageData(pixelImage, x, y);
}

■■■■:ドメイン
●●●●:ディレクトリパス


fig-8

キャンバス機能を使って反射効果を施すJavaScriptライブラリー「reflex.js」。他にもさまざまな加工用ライブラリーが用意されている

  今回取り上げたcanvasは利用範囲が広く、単に図形を描いたりするだけでなく、、動的に背景が変化するWebページを作ったり、「reflex.js」のようにページ上に配置した画像を加工して表示したりもできます。アイデア次第でいろいろな面白い使い方ができるでしょう。ぜひ試してみてください。

この連載の記事

一覧へ

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