daikiojm’s diary

ブログを書くときがやってきたどん!

Angularでプレビュー画像を自動回転する

Angularで画像プレビューを行う際に、画像のExif(Orientation)情報を見て自動で向きを回転させる方法です。

JavaScript-Load-Imageという便利なライブラリと、Reactでの使い方を紹介したありがたいブログ記事があったので、かなり簡単に実装することができました。 早速、実装していきたいと思います。

JavaScript-Load-Imageの導入

javascript exifとかでググるexif-jsというライブラリが真っ先にヒットするが、JavaScript-Load-Imageの方が断然使いやすいAPIが用意されている印象でした。

まずは、Angularプロジェクトにインストール

$ npm i --save blueimp-load-image

画像プレビュー&回転を行いたいコンポーネントに次のようにしてインポート(モジュール全体をまとめてインポートする必要あり)

import * as loadImage from 'blueimp-load-image';

Exifを見て自動で回転するプレビューを実装

まずは、テンプレート側

<!-- 画像を選択 -->
<input type="file" accept="image/*" (change)="onInputChange($event)"/>

<!-- 選択した画像を表示 -->
<img [src]="image" style="margin-top: 24px">

画像を選択させるinput要素のchangのイベントをイベントハンドラonInputChangeで受けています。

次に、クラス側

...
export class RotateComponent {
  public image: any = '';

  onInputChange(event: any) {
    const file = event.target.files[0];
    loadImage.parseMetaData(file, (data) => {
      const options = {
        orientation: null,
        canvas: true
      };
      if (data.exif) {
        options.orientation = data.exif.get('Orientation');
      }
      this.getDataUrl(file, options)
      .then(result => {
        this.image = result;
      });
    });
  }

  getDataUrl(blobImage: Blob, options: Object): Promise<any> {
    return new Promise((resolve) => {
      loadImage(blobImage, (canvas) => {
        resolve(canvas.toDataURL(blobImage.type));
      }, options);
    });
  }
}

イベントハンドラの引数から取得したfileをloadImageのparseMetaDataメソッドに渡し、Exif情報の取得を行った後、getDataUrlメソッドでは、loadImageで得られるcanvasをimgタグで表示できるData URL形式に変換しています。

試してみる

試しに、Exif(Orientation)情報が含まれる画像をアップロードしてみます。 ※ 右はJavaScript-Load-Imageを使わすにimgタグにプレビューした画像

f:id:daikiojm:20171123222415p:plain

参考

JavaScript(ES2015&React)で画像を扱う:リサイズとプレビュー表示