このページの本文へ

HTML5+JavaScriptでビデオエフェクターに挑戦! (4/6)

2010年05月12日 11時00分更新

文●古籏一浩

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

Canvasにエフェクトをかける

 動画をリアルタイムでCanvasに転送できるようになったので、次はCanvasに描画された画像にエフェクトをかけてみます。

 Canvas上のピクセルデータは以下のようにして取得できます。


var pxdata = con.getImageData(0, 0, 横幅, 縦幅);


 横幅と縦幅をCanvasと同じサイズにすれば、全体のピクセルデータを取得できます。ピクセルデータは配列として返され、配列要素にはRGBαの順番でピクセルデータが格納されています。

 ここでは簡単なサンプルとして、赤の輝度を半分にするエフェクトを作成します。赤の輝度を半分にする処理は、ピクセル値を2で割り、割った値を再度書き戻すだけです。あとはこの処理をすべてのピクセル分繰り返します。


for(var i=0; i<can.width*can.height; i++){
    pxdata.data[i*4] = Math.floor(pxdata.data[i*4] / 2);
    pxdata.data[i*4+3] = 255;
}


 Canvasは配列として読み出したピクセルを操作しただけだと結果が反映されないので、ピクセル処理の後に画像データを描画する必要があります。具体的には、以下のように記述します。


con.putImageData(pxdata, 0, 0);


 以上で、エフェクトが適用された状態で動画が描画されます。このエフェクト処理を高速に実行できれば、動画にリアルタイムでエフェクトを加えながら再生できるわけです。

 実際のスクリプトはサンプル04です。処理速度はマシンスペックによりますが、Mac Proクラスのマシンならエフェクトがかかった状態でもリアルタイムで再生できるでしょう。

fig4-1

動画を再生するとリアルタイムでエフェクトがかかりCanvasに描画される

サンプル04[HTML]


<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>映像にエフェクトをかける</title>
        <link rel="stylesheet" href="css/main.css" type="text/css" media="all">
        <script type="text/javascript" src="js/view.js"></script>
    </head>
    <body>
    <h1>映像にエフェクトをかける</h1>
    <video id="myVideo" controls autobuffer>
        <source src="movie.mov" width="384" height="216">
        <source src="movie.ogv" width="384" height="216">
    </video>
    <canvas id="myCanvas" width="384" height="216"></canvas>
    <div id="control">
        赤の輝度を半分にして映像をキャンバスに再描画します。<br>
    </div>
</body>
</html>


サンプル04[JavaScritp:view.js]


function sync(){
    var video = document.getElementById("myVideo");
    var can = document.getElementById("myCanvas");
    setInterval(function(){
        var con = can.getContext("2d");
        con.drawImage(video, 0, 0);
        var pxdata = con.getImageData(0, 0, can.width, can.height);
        for(var i=0; i<can.width*can.height; i++){
            pxdata.data[i*4] = Math.floor(pxdata.data[i*4] / 2);
            //pxdata.data[i*4+1] = pxdata.data[i*4+1];
            //pxdata.data[i*4+2] = pxdata.data[i*4+2];
            pxdata.data[i*4+3] = 255;
        }
        con.putImageData(pxdata, 0, 0);
    }, 1000/30);
}
window.addEventListener("load", sync, true);


この連載の記事

一覧へ

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