iOS
Swift

image fileのExifファイルを読み込む

More than 3 years have passed since last update.


目的

写真に付与されているExif内容を解析し位置情報を取り出す。まずはExif内容を読み取るまでを実装


環境

Xcode6.1.1


実装概要

参考文献を参照して自分なりに細かいところを書いています。Photo Libraryを読み出して写真を選択します。選択した写真に付与しているExifをimagePickerControllerで操作しています。写真情報はAssetsLibraryを用いてURLを取得して本体を直接見に行くようにしています。


ソースコードと詳細説明

私がはまったのはimportのところです。結局は以下を最低限読み込む必要があります。


import UIKit

import ImageIO

import AssetsLibrary


今回AssetsLibraryを使うのでAssetsLibraryは必須です。ImageIOはなんらかんらで必要でした。とくにDictionaryから値を引っ張ってくるときに必要になります。Photo Libraryを表示する関係でViewContollerは以下のような設定しておきます。


ViewController.swift

class ViewController: UIViewController,

UIImagePickerControllerDelegate,
UINavigationControllerDelegate{
// --- Outlets ---
// MARK: Outlets
@IBAction func didPushedButton(sender: AnyObject) {
self.imageLoad()
}


前提として、Storyboardにボタンを1つ配置し、"didPushedButton"に関連付けしておきます。

処理内容自体は"imageLoad()"内で記述しています。


ViewController.swift

// --- Methods ---

// MARK: Methods
func imageLoad(){
if UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){
var imagePicker = UIImagePickerController()

imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
imagePicker.allowsEditing = true
imagePicker.delegate = self

self.presentViewController(imagePicker, animated: true, completion: nil)
}
}


Photo Libraryを呼び出して表示するところまでを実装しています。

次にPhotoを選択したときに呼び出されるUIImagePickerControllerDelegate内を実装していきます。


ViewController.swift

// --- cancel action ---

// MARK: canncel action
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
self.dismissViewControllerAnimated(true, completion: nil)
}

// --- delegate ---
// MARK: PickerController delegate
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {

let assetURL:AnyObject = info[UIImagePickerControllerReferenceURL]! // get asset url
let url = NSURL(string: assetURL.description) // convert phrase to NSURL

let assetLib = ALAssetsLibrary()
assetLib.assetForURL(url, resultBlock: { (asset:ALAsset!) -> Void in

let metadata = asset.defaultRepresentation().metadata()

println(metadata)

if metadata[kCGImagePropertyGPSDictionary] == nil {
println("Location data nothing")
}else{
let gps = metadata[kCGImagePropertyGPSDictionary] as [NSObject: AnyObject]
let lat = gps[kCGImagePropertyGPSLatitude] as Double
let lng = gps[kCGImagePropertyGPSLongitude] as Double

NSLog("GPS Info Lat:%f Lng:%f", lat,lng)
}

self.dismissViewControllerAnimated(true, completion: nil)

}) { (error:NSError!) -> Void in

}

}


infoがいつのまにかNSDictionaryから[NSObject:AnyObject]と明示されるようになっています。また、型の厳密性がましており


let assetURL:AnyObject = info[UIImagePickerControllerReferenceURL]!


としないとダメでした。AnyObjectをそのまま使用してNSURLを生成できないので、descriptionでNSStringにしています。metadataは以下のところで取得しています。


let metadata = asset.defaultRepresentation().metadata()


サンプル画像のmetaデータは以下の様な内容でした。

[{Exif}: {

ColorSpace = 1;
ComponentsConfiguration = (
1,
2,
3,
0
);
ExifVersion = (
2,
2,
1
);
FlashPixVersion = (
1,
0
);
PixelXDimension = 1500;
PixelYDimension = 1001;
SceneCaptureType = 0;
}, ColorModel: RGB, DPIWidth: 72, Orientation: 1, DPIHeight: 72, Depth: 8, PixelHeight: 1001,
{TIFF}: {
Orientation = 1;
ResolutionUnit = 2;
XResolution = 72;
YResolution = 72;
}, PixelWidth: 1500]

うーん、GPS情報がない。。。

iPhotoとかで見ると確かにGPS情報が入っているのですが・・・。


参考文献

http://qiita.com/ozw_sei/items/f8c99a7adb321a92a12f