LoginSignup
9
11

More than 5 years have passed since last update.

【Swift4】iOS11から導入されたAVCapturePhotoSettingsのプロパティを使って写真に位置情報を格納する

Last updated at Posted at 2017-12-13

はじめに

iOS10から導入されたAVCapturePhotoSettings()にOS11よりメタデータのプロパティが追加されました。
カメラ撮影から写真保存までのプロセスはiOSのバージョンで色々あって、古い(?)方式の情報はままあるのですが、
AVCapturePhotoSettingsでは、Appleのサンプルコードに位置情報の格納方法の記載がなく、このプロパティを発見するまではあちこち放浪しました。

AVCapturePhotoSettingsのプロパティ

Swift
var metadata: [String : Any] { get set }

このプロパティに位置情報を格納することができます。
位置情報は、CLLocationと違って±がありませんので要注意です。
経度、緯度の±の代わりに"N"、"S"、"E"、"W"で指示します。

ソースコード

Swift

    func configure(location: CLLocation)
    {
        var photoSettings = AVCapturePhotoSettings()

        photoSettings.metadata = self.setMeta(location: location)

        // 以下適当に省略

        let photoCaptureProcessor = PhotoCaptureProcessor(with: photoSettings, willCapturePhotoAnimation:
        {
            // 省略
        }, livePhotoCaptureHandler: { capturing in
            // 省略
        }, completionHandler: { photoCaptureProcessor in
            // 省略
        })

        self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureProcessor)
    }

    /// 位置情報をメタデータ用Dictionaryにに書き込む
    ///
    /// - Parameter location: 位置情報
    /// - Returns: メタデータ用Dictionary
    private func setMeta(location: CLLocation) -> Dictionary<String, Any>
    {
        // メタデータ
        //exif情報を準備する
        let gps = NSMutableDictionary()
        var exif = Dictionary<String, Any>()
        var meta = Dictionary<String, Any>()

        // 位置情報
        gps.setObject(location.timestamp,   forKey: kCGImagePropertyGPSDateStamp as! NSCopying)
        gps.setObject(location.timestamp,   forKey: kCGImagePropertyGPSTimeStamp as! NSCopying)

        // 経度の設定

        // 緯度情報を取得
        var latitude = location.coordinate.latitude
        var gpsLatitudeRef = "N"        // 北緯
        if latitude < 0
        {
            latitude = -latitude;       // マイナス値はプラス値に反転
            gpsLatitudeRef = "S"        // 南緯
        }
        gps.setObject(gpsLatitudeRef,   forKey: kCGImagePropertyGPSLatitudeRef as! NSCopying)
        gps.setObject(latitude,         forKey: kCGImagePropertyGPSLatitude as! NSCopying)

        // 経度情報を取得
        var longitude = location.coordinate.longitude
        var gpsLongitudeRef = "E"       // 東経
        if longitude < 0
        {
            longitude = -longitude;     // マイナス値はプラス値に反転
            gpsLongitudeRef = "W"       // 西経
        }
        gps.setObject(gpsLongitudeRef,  forKey: kCGImagePropertyGPSLongitudeRef as! NSCopying)
        gps.setObject(longitude,        forKey: kCGImagePropertyGPSLongitude as! NSCopying)

        gps.setObject(0,                forKey: kCGImagePropertyGPSAltitudeRef as! NSCopying)
        gps.setObject(0,                forKey: kCGImagePropertyGPSAltitude as! NSCopying)

        exif[kCGImagePropertyGPSDictionary as String] = gps

        exif[kCGImagePropertyExifUserComment as String] = "コメント"

        meta[kCGImagePropertyExifDictionary as String] = exif

        return meta
    }

9
11
2

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
9
11