5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

初めてのアドベントカレンダーAdvent Calendar 2021

Day 4

Exifから画像がGPS情報を含むか判定【Vue.js】

Last updated at Posted at 2021-12-03

はじめに

初めてのアドベントカレンダーの4日目を担当します,ぽらです!
自分は,画像に含まれるGPS情報を取得する方法,GPS情報がない場合のエラーハンドリングについて記載します.

Vue.jsに慣れていない初心者の方や,フロントで画像のGPS情報のバリデーション方法を探している方などの参考になれば幸いです!

画像に含まれるGPS情報について

最近は,スマートフォンで写真を撮ることが多くあると思います.その際,位置情報をONにしていると画像のExifの中にGPS情報を含めることができます.

Exifとは

Exifは,カメラで撮影された際に様々なメタデータを格納し,画像データに埋め込まれています.
Exchangeable image file format - Wikipedia - ウィキペディア
この情報を取得することで,画像が撮影された日時や,GPS機能による位置情報が確認できます.

下準備

Vueプロジェクトの作成

本記事ではプロジェクト作成は割愛させていただきました.こちらの記事通りに進めれば作成できると思います.
http://localhost:8080/にサンプルが表示されれば成功です.

今回はVueのバージョン2.6.11の環境下で実装していますが,Vue3系での実装も実際に確認しました.

ページ作成

作成したVueプロジェクト内のsrc/components配下にpagesというディレクトリを作成し,pages内にInput.vueというファイルを作成します.ここに画像をアップロードできるようにしていきます.

ルーティング設定

トップ画面を使って手軽に試せるようにルーティング設定を行います.今回は最低限の設定で行っていきます.

src/router.js
import Vue from 'vue';
import Router from 'vue-router';
import Input from './components/pages/Input.vue';

Vue.use(Router)
const router = new Router({
    mode: 'history',
    routes: [
      {
        path: '/',
        name: 'input',
        component: Input
      },
    ]
})
export default router
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'; // ++

Vue.config.productionTip = false

new Vue({
  router, //++
  render: h => h(App),
}).$mount('#app')
App.vue
<template>
  <router-view />
</template>

Vue Routerについてより詳しく知りたい方はこちら

画像のアップロード

画像の入力ができるようにします.今回はjpeg画像を対象に実装しています.

Input.vue
<template>
  <div class="Input">
    <h1>画像のGPS情報取得</h1>
    <div>
      <input type="file" accept="image/jpeg"/>
    </div>
  </div>
</template>

スクリーンショット 2021-12-03 16.15.09.png

ファイルを選択してアップロードできるようになりました.

画像の情報を見てみる

次に,ファイルの情報を取得できるようにします.
onImageChangeというメソッドを追加しました.

App.vue
<template>
  <div class="Input">
    <h1>画像のGPS情報取得</h1>
    <div>
      <input type="file" accept="image/jpeg" @change="onImageChange" />
    </div>
  </div>
</template>

<script>
  export default {
    methods: {
      onImageChange(e) {
        const files = e.target.files;
        console.log(files[0]);
      },
    },
  };
</script>

実際に画像を入力します.
スクリーンショット 2021-12-03 16.20.13.png

このように画像が撮影された日時などは取得できます.
ただ,このままではExifにはアクセスできていません.
そこで,今回はblueimp/JavaScript-Load-Imageというライブラリを使用します.

Exif情報を取得

##Exif情報を出力してみる
npmでライブラリのインストールを行います.

npm install blueimp-load-image

インストールしたblueimp-load-imagからloadImageをインポートして,Exif情報を出力します.

App.vue
<template>
~~
</template>

<script>
  import loadImage from "blueimp-load-image";

  export default {
    methods: {
      checkGPS(file) {
        loadImage.parseMetaData(file, function (data) {
          console.log("Exif data: ", data.exif);
        });
      },
      onImageChange(e) {
        const files = e.target.files;
        this.checkGPS(files[0]);
      },
    },
  };
</script>

スクリーンショット 2021-12-03 16.44.39.png

機種情報などが出力できているのがわかります.このようにExifには様々な情報が含まれ,TAGIDに情報が紐づいています.
TAGIDの一覧はこちら

実際に各項目にはparseMetaData内で,

data.exif.get("GPSLongitude");

のようにget("欲しい情報")でアクセスできます.

位置情報を含むか判定

GPS情報を取得することはできました.
ただ,このままではGPSを含まない場合には空の値にアクセスしてしまうのでGPS情報を含まない場合にはエラー表示できるようにします.

App.vue
<script>
 ~~
      checkGPS(file) {
        loadImage.parseMetaData(file, function (data) {
          if (data.exif && data.exif.get("GPSInfo")) {
            console.log(data.exif.get("GPSInfo"));
          } else {
            alert(
              "エラー: " + file.name + "\n位置情報を含む画像を選択してください"
            );
          }
        });
      },
~~
</script>

今回は,試しにGPS情報を含まない自分のアイコンpola_.jpgを入力しました.
スクリーンショット 2021-12-03 17.23.27.png

ちゃんとエラーハンドリングできました!

念のため実装したInput.vueを載せておきます.

Input.vue
<template>
  <div class="Input">
    <h1>画像のGPS情報取得</h1>
    <div>
      <input type="file" accept="image/*" @change="onImageChange" />
    </div>
  </div>
</template>

<script>
  import loadImage from "blueimp-load-image";

  export default {
    methods: {
      checkGPS(file) {
        loadImage.parseMetaData(file, function (data) {
          if (data.exif && data.exif.get("GPSInfo")) {
            console.log(data.exif.get("GPSInfo"));
          } else {
            alert(
              "エラー: " + file.name + "\n位置情報を含む画像を選択してください"
            );
          }
        });
      },
      onImageChange(e) {
        const files = e.target.files;
        this.checkGPS(files[0]);
      },
    },
  };
</script>

おわりに

この度,ハッカソンに参加していた他の学生さんの呼びかけのおかげで,勇気を出してアドベントカレンダーに初挑戦できました!

記事を書くこともほぼ初めてなので,至らない点,ご指摘等ありましたらコメントいただけると幸いです.

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?