このページの本文へ

  • twitterでつぶやく
  • はてなブックマークに登録
  • del.icio.usに登録
  • livedoorクリップに登録
  • Buzzurlに登録
  • StumbleUponに登録
  • Google Bookmarksに登録
  • Facebookでシェア
  • Yahoo!ブックマークに登録
  • お気に入りに登録
  • 本文印刷

古籏一浩のJavaScriptラボ ― 第14回

HTML5のcanvasで作る画像フィルター

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」のようにページ上に配置した画像を加工して表示したりもできます。アイデア次第でいろいろな面白い使い方ができるでしょう。ぜひ試してみてください。

この連載の記事

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く

みんなが買ってる最新アイテムはコレだ!

VOCALOID3 スターターIA ARIA ON THE PLANETES

VOCALOID3 スターターIA ARIA ON THE PLANETES

ヤマハ

17,745円〜

24人が購入

Google上位表示 64の法則 (WEB PROFESSIONAL)

Google上位表示 64の法則 (WEB PROFESSIONAL)

アスキー・メディアワークス

2,499円〜

72人が購入

標準HTML5タグリファレンス (WEB PROFESSIONAL)

標準HTML5タグリファレンス (WEB PROFESSIONAL)

アスキー・メディアワークス

2,205円〜

59人が購入

Speck MacBook Air 13型 See Thru - Clear SPK-MBA13-SEE-CLR

Speck MacBook Air 13型 See Thru - Clear SPK-MBA13-SEE-CLR

スペックコンピュータ

4,262円〜

23人が購入

jQuery Mobile スマートフォンサイト デザイン入門 (WEB PROFESSIONAL)

jQuery Mobile スマートフォンサイト デザイン入門 (WEB PROFESSIONAL)

アスキー・メディアワークス

2,499円〜

40人が購入

メモリーカード 32GB (PCH-Z321J)

メモリーカード 32GB (PCH-Z321J)

ソニー・コンピュータエンタテインメント

7,772円〜

9人が購入

iPhone 4S/4 防指紋性・高光沢機能性フィルム PRO GUARD AF for iPhone 4S/4 / PGAF-IPH4

iPhone 4S/4 防指紋性・高光沢機能性フィルム PRO GUARD AF for iPhone 4S/4 / PGAF-IPH4

マイクロソリューション Micro Solution Inc.

61人が購入

Amazon.co.jp