nyabot’s diary

電気猫の夢を見るお話

MJPG-streamerの表示調整(Javascriptでcanvasに表示する画像を90°回転させる)

ロボットにwebカメラを取り付けるとき、基盤の形状と収めるスペースの都合で、90度傾けることになった。
カメラが90度傾いているので、撮影される画像・映像も当然90度傾く。
MJPG-streamerでストリーミングしたいと思っていたのだけれど、ただ表示させるだけだと映像が横を向く。こまった。

ラズパイ用のカメラモジュールを使用する場合は、オプションで角度の変更ができるみたい。
webカメラにはそういうオプションがなさそうだったので、Javascriptで表示するときに調整した。

webカメラを90度傾けて使うというのはたぶん極めて特殊なケースだし、正直もうやらない気がするけど、肝心なところだけメモ。

var imgUrl = "画像のURL";
var imgWidth = "画像の幅";
var imgHeight = "画像の高さ";

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');

canvas.width = imgWidth;
canvas.height = imgHeight;


//画像を90度回転させるため、高さと幅を入れ替えて使用する
var rImgWidth = imgHeight;
var rImgHeight = imgWidth;

ctx.rotate(90 * Math.PI / 180);//時計回りに90度回転させる
ctx.drawImage(imgUrl, 0, -rImgWidth, rImgWidth, rImgHeight);

左上の点を軸として指定した角度回転するので、時計回りに回転させた場合は回転後の幅(=回転前の高さ)と同じだけ描画開始位置を右(下)にずらすのがポイント。

CSSのtransform:rotate()で回転させる(追記)

もっと簡単な方法としては、cssでtransform: rotate(90deg);を指定してcanvas要素ごと回転させてしまう方法もある。
しかし、一つのcanvasに描画する画像が複数ある場合、この方法では特定の画像だけを回転させる(画像ごとに角度を変える)ことはできない。

回転させるためのコードはこんな感じ。キャンバスのサイズ比率(横:縦)は回転前が4:3、回転させたあとが3:4の場合。

var canvas = document.getElementById("canvas");
var canvasHeight;
var canvasWidth;
var isPortrait;

// ウィンドウの高さと幅の短い方にキャンバスの大きさを合わせる
if(window.innerWidth < window.innerHeight){
    isPortrait = true;
}else{
    isPortrait = false;
}

if(isPortrait){// 画面幅<画面高さ
    canvasHeight = window.innerWidth;// 90度回転させるため、ウィンドウの幅を回転前のキャンバスの高さとして指定する
    canvasWidth = 4*canvasHeight/3;
}else{// 画面幅>画面高さ
    canvasWidth = window.innerHeight;// 90度回転させるため、ウィンドウの高さを回転前のキャンバスの幅として指定する
    canvasHeight = 3* canvasWidth/4;
}

canvas.width = canvasWidth;
canvas.height = canvasHeight;

canvas.style.transform = 'rotate(90deg)';
canvas.style.transformOrigin = canvasHeight / 2 + "px";

以上。

つづく。