イナヅマTVログ

[JavaScript] Memo, Web Cam映像をCanvasへ鏡像(反転)表示

| 0件のコメント

Web CamもJavaScriptで制御できるステキな時代。
そのまま表示させると、当たり前だけど反転してるように見えて気持ち悪いので鏡像表示させてみる。
後でゴニョゴニョしたいのでCanvas上で鏡像にする手順メモ。

Web Camを表示

video tagを設置。

<video width="640" height="480" src="" id="web_cam"></video>
<canvas id="features" width="640" height="480" style="display: inline;"></canvas>

JavaScript

var video = document.getElementById( "web_cam");
 
function init ( video ) {
    video.play();
}
 
// web cam access
navigator.getUserMedia(
    { video: true },
    function ( stream ) {
 
        if ( typeof video.mozSrcObject !== "undefined" ) {
            // moz
            video.mozSrcObject = stream;
        } else {
            // others
            video.src = ( window.URL && window.URL.createObjectURL( stream ) ) || stream;
        }
 
        // 初期処理
        init( video );
    },
    function ( error ) {
 
        console.log( error );
    }
);

navigator.getUserMedia
MDN: Navigator.getUserMedia

プロンプトを表示し、ユーザにカメラやマイクといったメディアデバイスの使用を許すかどうかを尋ねます。

/**
 * @params {object} constraints 
 * @params {function} successCallback
 * @params {function} errorCallback
 */
navigator.getUserMedia ( constraints, successCallback, errorCallback );

getUserMedia はvendor prefixが付くようなので次のようにしています。

navigator.getUserMedia = navigator.getUserMedia ||
                            navigator.webkitGetUserMedia ||
                            navigator.mozGetUserMedia ||
                            navigator.msGetUserMedia;

window.URL
MDN: window.URL

window.URL = window.URL ||
            window.webkitURL ||
            window.mozURL ||
            window.msURL;

Canvasへ鏡像表示

var features = document.getElementById( "features"),
    features_ctx;
 
function loop () {
    requestAnimationFrame( loop );
 
    if ( video.readyState === video.HAVE_ENOUGH_DATA ) {
 
        features_ctx.drawImage( video, 0, 0, 640, 480 );
    }
}
 
function init ( video ) {
    video.play();
 
    features_ctx = features.getContext( "2d" );
    // flip
    features_ctx.translate( 640, 0 );
    features_ctx.scale( -1, 1 );
 
    loop();
}

requestAnimationFrame は次のようにしています。

var lastTime = 0;
var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
 
for ( var x = 0; x < vendors.length && !self.requestAnimationFrame; ++ x ) {
 
    self.requestAnimationFrame = self[ vendors[ x ] + 'RequestAnimationFrame' ];
    self.cancelAnimationFrame = self[ vendors[ x ] + 'CancelAnimationFrame' ] || self[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
}
 
if ( self.requestAnimationFrame === undefined && self.setTimeout !== undefined ) {
 
    self.requestAnimationFrame = function ( callback ) {
 
        var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
        var id = self.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall );
        lastTime = currTime + timeToCall;
        return id;
    };
 
}

以下を参考にしています。

http://paulirish.com/2011/requestanimationframe-for-smart-animating/
http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
three.js

コードをまとめると以下のようになります。

var video = document.getElementById( "web_cam"),
    features = document.getElementById( "features"),
    features_ctx;
 
function loop () {
    requestAnimationFrame( loop );
 
    if ( video.readyState === video.HAVE_ENOUGH_DATA ) {
 
        features_ctx.drawImage( video, 0, 0, 640, 480 );
    }
}
 
function init ( video ) {
    video.play();
 
    features_ctx = features.getContext( "2d" );
    // flip
    features_ctx.translate( 640, 0 );
    features_ctx.scale( -1, 1 );
 
    loop();
}
 
// web cam access
navigator.getUserMedia(
    { video: true },
    function ( stream ) {
 
        if ( typeof video.mozSrcObject !== "undefined" ) {
            // moz
            video.mozSrcObject = stream;
        } else {
            // others
            video.src = ( window.URL && window.URL.createObjectURL( stream ) ) || stream;
        }
 
        // 初期処理
        init( video );
    },
    function ( error ) {
 
        console.log( error );
    }
);

demo
Web Camが使用できるマシンでChromeなどでアクセスして下さい。

videoを鏡像にするもう一つの方法

video tagをCSS3 transformを使い反転させる方法もあります。

video.style.cssText += "transform: rotateY(180deg);-webkit-transform:rotateY(180deg);-moz-transform:rotateY(180deg);-ms-transform:rotateY(180deg);";

コメントを残す

必須欄は * がついています