JavaScript

【JavaScript】JPG画像のEXIF情報を取得して回転表示させる

MAX

JPEG画像はフォトビューワー等で表示すると正しい向きに表示されていても、ブラウザにアップロードすると、向きがおかしく表示されることがある。

JPEG画像はEXIFデータを保持しており、その中のOrientationが画像の回転や反転情報となるため、Orientationの値を反映してブラウザで表示させる。

EXIF情報の取得はexif.jsを用いる。

exif.jsはCDNでも公開されており、本記事ではCDNを利用する。

exif情報の取得や画像の読込処理は非同期で行われるため、ネストが深くなるのを避けるために、async/awaitを用いる。

スポンサーリンク

exif.jsの設定(html)

1<script type="text/javascript" src="{{ url_for('static', filename='js/rotate_image.js') }}"></script> 
2<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.3.0/exif.min.js"></script>
3<form method="post" enctype="multipart/form-data">
4   <input type="file" name="imgFile" id="imgFile">
5</form> <img id="imgPreview">

ファイルが選択された時に、JavaScriptでブラウザに表示する。

画像回転表示のメイン処理(js)

1/*
2 * 画像ファイル選択時にブラウザに表示する
3 */
4document.getElementById("imgFile")
5    .addEventListener("change", async function (e) {
6    
7    let imgElement = new Image();
8
9    //imgタグの要素取得
10    let imgPreview = document.getElementById("imgPreview");
11
12    if (e.target.files[0]){
13        //exif情報を取得する。
14        //取得には時間がかかるのでasync/awaitを使って処理を待つ。
15        let orientation = await getOrientation(e.target.files[0]);
16
17        //orientationから回転角度を設定する
18        const angle = setAngle(orientation);
19        
20        //blobUrlを作成する
21        let blobUrl = window.URL.reateObjectURL(e.target.files[0]);
22
23        //blobURLから画像データを読み込む
24        //画像の読込には時間がかかるのでasync/awaitで処理を待つ。
25        imgElenent = await loadImage(blobUrl);
26        
27        imgPreview.src = imgElement.src;
28
29        //transformで回転角度を設定する。
30        imgPreview.style.transform = "rotate(" + angle + "deg)";
31        
32    }
33});

exifdata.Orientation取得処理

exif情報の取得は非同期で行われるため、Promiseを使って処理を待つ。exif情報を取得した際に、そのままfunction内で処理を進めることも可能だが、コールバックが重なってネストが深くなるのを避けるために、Promiseを使う。

1function getOrientation(imgFile){
2    return new Promise( (resolve, reject) => {
3        EXIF.getData(imgFile, function() {
4            resolve(imgFile.exifdata.Orientation);
5            //取得したimgFile.exifdata.Orientationに対し、function内で処理を進めることも可能
6        });
7    });
8}

回転角度の設定処理

取得したOrientationの値に合わせて、回転させる角度を設定する。

1function setAngle(orientation){
2    switch(orientation){
3    case 1:    //回転なし
4        angle = 0;
5        break;
6    case 3:    //元画像を180度回転しているので、180度回転させて元に戻す。
7        angle = 180;
8        break;
9    case 6:    //元画像を270度回転しているので、90度回転させて元に戻す。
10        angle = 90;
11        break;
12    case 8:    //元画像を90度回転しているので、270度回転させて元に戻す。
13        angle = 270;
14        break;
15    default:
16        angle = 0;
17        break;
18    }
19    return angle;
20}

画像データの読み込み処理

ここまでで必要な回転角度は取得できたので、画像データを取得して回転表示させる。画像データ読込も非同期なのでPromiseを使用する。

1function loadImage(blobImg){
2    return new Promise( (resolve, reject) => {
3        const img = new Image();
4        img.onload = () => resolve(img);
5        img.onerror = (e) => reject(e);
6        img.src = blobImg;
7    });
8}

画像を90度回転させると、縦と横が入れ替わるため、場合によっては、画像のサイズを取得し、回転角度に合わせて表示させることも必要かもしれない。

スポンサーリンク
ABOUT ME
MAX
MAX
ITエンジニア、データサイエンティスト
新卒でSIerに入社し、フリーランスになってWEB系へ転向。
その後AIの世界へ足を踏み入れ、正社員に戻る。 テーブルデータの分析がメイン。
スポンサーリンク
記事URLをコピーしました