MotoJapan's Tech-Memo

技術めも

【Javascript】video/canvasを上下180度反転(回転)させる方法 【お家IT#10】

本件の実装の一部 
motojapan.hateblo.jp

前回の続き 
motojapan.hateblo.jp

目次 

前回までの投稿でバックエンドとフロントエンドの通信周りは整理した。
ここからはWebカメラの操作を進める。

今回は、video/canvasを上下180度反転(回転)させるたい。
原因は、Windowsタブレットのカメラが上下反転して表示されてしまう。(ハードウェア原因)
スマホなら問題ないのだが、気持ち悪いので補正する。

Videoの回転

HTML5&CSS3の組み合わせで、webkitのtransform rotationを使えば回転可能
回転中心は、Video領域の中心である

//**************** html **********************

<video id="camera" width="720px" autoplay></video>

//**************** css ***********************

<style type="text/css">
.Rotate0{
    -webkit-transform: rotate(0deg);
}
.Rotate180{
    -webkit-transform: rotate(180deg);
}
</style>

//************ javascript ********************

//関数から動的に変更する
<script type="text/javascript">
function rotate_video(degree) {
    var video = document.getElementById('camera');
    //スタイルを適用する関数を定義
    video.className = "Rotate"+degree;
}

//元の画像から180度反転する
rotate_video(180)
//元の画像に戻る
rotate_video(0)
</script>

Canvasの回転

Canvasの回転はテクニックが必要で、
単純にCanvasのcontextをrotateすると回転中心が(x, y) = (0, 0)つまり、左上部になってしまい、Canvasの中心では回転しない
なので、translate(移動1) -> rotate(回転) -> translate(移動2)の手順で意図した回転になる。
移動1は、Canvas中心が(x, y) = (0, 0)になるように、画像半分の縦横長で移動
移動2は、Canvas中心が移動1実行前の位置に戻す為に、移動1と同じだけ反対方向に移動

今回はcanvasを回転させてから、videoタグの画像を張り付けるようにします。

//**************** html **********************

<canvas id="canvas"></canvas>

//**************** css ***********************

//不要

//************ javascript ********************

//関数から動的に変更する
<script type="text/javascript">
function rotate_canvas(degree) {
    var canvas = document.getElementById('canvas');
    //canvasの描画モードを2sに
    var ctx = canvas.getContext('2d');
 
   //Canvasに設定するサイズを決める
    //(例えば、videoの縦幅横幅を取得)
    var video = document.getElementById('camera');
    var w = video.offsetWidth;
    var h = video.offsetHeight;

    //同じサイズをcanvasに指定
    canvas.setAttribute("width", w);
    canvas.setAttribute("height", h);

    //一旦canvasをリセットしたければ
    //ctx.clearRect(0, 0, canvas.width, canvas.height);

    //[移動1] Canvas中心が(x, y) = (0, 0)になるように、画像半分の縦横長で移動
    ctx.translate(w/2, h/2);
    //[回転]
    ctx.rotate(degree * Math.PI / 180);
    //[移動2] Canvas中心が移動1実行前の位置に戻す為に、移動1と同じだけ反対方向に移動
    ctx.translate( -1 * w/2, -1 * h/2 );    

    //videoの画像をcanvasにコピー
    ctx.drawImage(video, 0, 0, w, h);
}

//元の画像から180度反転する
rotate_canvas(180)
//元の画像に戻る
rotate_canvas(0)
</script>

以上。
次回はカメラ切り替えを予定。