JPEG画像はフォトビューワー等で表示すると正しい向きに表示されていても、ブラウザにアップロードすると、向きがおかしく表示されることがある。
JPEG画像はEXIFデータを保持しており、その中のOrientationが画像の回転や反転情報となるため、Orientationの値を反映してブラウザで表示させる。
EXIF情報の取得はexif.jsを用いる。
exif.jsはCDNでも公開されており、本記事ではCDNを利用する。
exif情報の取得や画像の読込処理は非同期で行われるため、ネストが深くなるのを避けるために、async/awaitを用いる。
スポンサーリンク
exif.jsの設定(html)
<script type="text/javascript" src="{{ url_for('static', filename='js/rotate_image.js') }}"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.3.0/exif.min.js"></script>
<form method="post" enctype="multipart/form-data">
<input type="file" name="imgFile" id="imgFile">
</form>
<img id="imgPreview">
ファイルが選択された時に、JavaScriptでブラウザに表示する。
画像回転表示のメイン処理(js)
/*
* 画像ファイル選択時にブラウザに表示する
*/
document.getElementById("imgFile")
.addEventListener("change", async function (e) {
let imgElement = new Image();
//imgタグの要素取得
let imgPreview = document.getElementById("imgPreview");
if (e.target.files[0]){
//exif情報を取得する。
//取得には時間がかかるのでasync/awaitを使って処理を待つ。
let orientation = await getOrientation(e.target.files[0]);
//orientationから回転角度を設定する
const angle = setAngle(orientation);
//blobUrlを作成する
let blobUrl = window.URL.reateObjectURL(e.target.files[0]);
//blobURLから画像データを読み込む
//画像の読込には時間がかかるのでasync/awaitで処理を待つ。
imgElenent = await loadImage(blobUrl);
imgPreview.src = imgElement.src;
//transformで回転角度を設定する。
imgPreview.style.transform = "rotate(" + angle + "deg)";
}
});
exifdata.Orientation取得処理
exif情報の取得は非同期で行われるため、Promiseを使って処理を待つ。exif情報を取得した際に、そのままfunction内で処理を進めることも可能だが、コールバックが重なってネストが深くなるのを避けるために、Promiseを使う。
function getOrientation(imgFile){
return new Promise( (resolve, reject) => {
EXIF.getData(imgFile, function() {
resolve(imgFile.exifdata.Orientation);
//取得したimgFile.exifdata.Orientationに対し、function内で処理を進めることも可能
});
});
}
回転角度の設定処理
取得したOrientationの値に合わせて、回転させる角度を設定する。
function setAngle(orientation){
switch(orientation){
case 1: //回転なし
angle = 0;
break;
case 3: //元画像を180度回転しているので、180度回転させて元に戻す。
angle = 180;
break;
case 6: //元画像を270度回転しているので、90度回転させて元に戻す。
angle = 90;
break;
case 8: //元画像を90度回転しているので、270度回転させて元に戻す。
angle = 270;
break;
default:
angle = 0;
break;
}
return angle;
}
画像データの読み込み処理
ここまでで必要な回転角度は取得できたので、画像データを取得して回転表示させる。画像データ読込も非同期なのでPromiseを使用する。
function loadImage(blobImg){
return new Promise( (resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = (e) => reject(e);
img.src = blobImg;
});
}
画像を90度回転させると、縦と横が入れ替わるため、場合によっては、画像のサイズを取得し、回転角度に合わせて表示させることも必要かもしれない。
スポンサーリンク
スポンサーリンク