【JavaScript】iPhoneで撮影した画像をアップロードすると回転してしまう時の解決方法

【JavaScript】iPhoneで撮影した画像をアップロードすると回転してしまう時の解決方法

input:file でアップロード画像を選択する際に、選択した画像データを取得してプレビュー表示するといったケースがあるはずです。

例えばこんなコード。

document.querySelector('input[type="file"]').addEventListener('change', function() {
    var reader = new FileReader();

    reader.onload = () => {
      // 画像を作成
      var img = new Image();
      img.src = reader.result;
      document.body.appendChild(img);
    };

    reader.readAsDataURL(this.files[0]);
});

デスクトップブラウザでは特に問題ありませんが、iPhoneで撮影した写真を選択・プレビューしようとすると、勝手に画像が90度回転してしまいます。iPhoneでの撮影画像にはExifデータがあり、そのデータをもとに端末で処理されているのが原因です。

とはいえ、これは明らかなバグになりますので回転させないように実装する方法をご紹介します。

JavaScript-Load-Imageで正しい方向の画像を取得

回転させないようにするにはJavaScript-Load-imageというライブラリを使用します。

https://github.com/blueimp/JavaScript-Load-Image

はじめにライブラリを読み込みます。

<script src="js/load-image.all.min.js"></script>

ライブラリを読み込むと、グローバル変数に loadImage が追加されるので、loadImage.parseMetaData メソッドを利用して画像の傾きを取得して正しい方向にセットします。

document.querySelector('input[type="file"]').addEventListener('change', function() {
    var file = this.files[0];

    loadImage.parseMetaData(file, (data) => {
      var options = {
        canvas: true
      };
      if (data.exif) {
        options.orientation = data.exif.get('Orientation');
      }
      loadImage(file, (canvas) => {
        var dataUri = canvas.toDataURL('image/jpeg');
        // 画像を作成
        var img = new Image();
        img.src = dataUri; 
        document.body.appendChild(img);
      }, options);
    });
  }
});

そして loadImage 関数でファイルを読み込み、canvas経由で画像を取得しdataURIスキームでデータを取り出します。

注意点は、この後にサーバーにアップロードする画像データは回転しているままですので、サーバー側でも別途処理が必要になります。

五十川 洋平(Yohei Isokawa)

五十川 洋平(Yohei Isokawa)

フロントエンドエンジニア/面白法人カヤックなどのWeb制作会社に勤務したのち、故郷の新潟に戻り独立。JSフレームワークAngularやFirebase、Google Cloud Platformを使ったWebアプリ開発が得意。 また、Udemyのプログラミング解説の講師、writer.appの自主開発や上越TechMeetupの主催などを行っています。

プロフィール

©Copyright 2022 Yohei Isokawa All Rights Reserved.