はじめに
初めてのアドベントカレンダーの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
というファイルを作成します.ここに画像をアップロードできるようにしていきます.
ルーティング設定
トップ画面を使って手軽に試せるようにルーティング設定を行います.今回は最低限の設定で行っていきます.
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
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')
<template>
<router-view />
</template>
Vue Routerについてより詳しく知りたい方はこちら
画像のアップロード
画像の入力ができるようにします.今回はjpeg
画像を対象に実装しています.
<template>
<div class="Input">
<h1>画像のGPS情報取得</h1>
<div>
<input type="file" accept="image/jpeg"/>
</div>
</div>
</template>
ファイルを選択してアップロードできるようになりました.
画像の情報を見てみる
次に,ファイルの情報を取得できるようにします.
onImageChange
というメソッドを追加しました.
<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>
このように画像が撮影された日時などは取得できます.
ただ,このままではExifにはアクセスできていません.
そこで,今回はblueimp/JavaScript-Load-Imageというライブラリを使用します.
Exif情報を取得
##Exif情報を出力してみる
npmでライブラリのインストールを行います.
npm install blueimp-load-image
インストールしたblueimp-load-imag
からloadImage
をインポートして,Exif情報を出力します.
<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>
機種情報などが出力できているのがわかります.このようにExifには様々な情報が含まれ,TAGID
に情報が紐づいています.
TAGIDの一覧はこちら.
実際に各項目にはparseMetaData
内で,
data.exif.get("GPSLongitude");
のようにget("欲しい情報")
でアクセスできます.
位置情報を含むか判定
GPS情報を取得することはできました.
ただ,このままではGPSを含まない場合には空の値にアクセスしてしまうのでGPS情報を含まない場合にはエラー表示できるようにします.
<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
を入力しました.
ちゃんとエラーハンドリングできました!
念のため実装した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>
おわりに
この度,ハッカソンに参加していた他の学生さんの呼びかけのおかげで,勇気を出してアドベントカレンダーに初挑戦できました!
記事を書くこともほぼ初めてなので,至らない点,ご指摘等ありましたらコメントいただけると幸いです.