質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

2374閲覧

Swiftでフォトライブラリ内の画像のExif情報(位置情報)を編集したい

oajfodjooaidjoa

総合スコア6

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

2クリップ

投稿2019/02/05 09:34

Swiftでフォトライブラリに保存済の画像の位置情報を書き換えて、上書き保存する方法を知りたいです。
画像の新規保存のタイミングで位置情報を付与してフォトライブラリに保存することは出来たのですが、保存済みの画像の位置情報の書き換えがうまくいかず質問させていただきました。

バージョン情報

  • Swift 4.2

詳細

tilltue/TLPhotoPicker: ???? multiple phassets picker for iOS lib. like a facebook

というライブラリを使って複数選択可能な画像選択画面を実装していました。最初に選択した画像の位置情報を次の画面に渡す仕様になっているのですが、ライブラリで提供しているカメラを使用した時に画像の位置情報が入っていないことに気づきました。

UIImagePickerControllerDelegateにconformしているclass、TLPhotoPickerViewControllerで実装されているimagePickerController(_:didFinishPickingMediaWithInfo:)内で画像が保存されていて、保存後のdelegateメソッド、selectedPhoto(picker: TLPhotosPickerViewController, at: Int)というメソッドでユーザーが撮影した画像のPHAssetの変更を行うようになっています。

このメソッド内で選択した画像のPHAssetを取り出しPHAssetの方に位置情報を保存することには成功したのですが画像自体のExif情報を見ると位置情報が保存されていませんでした。

PHAssetのlocationの変更だけでなく画像自体の位置情報も更新したい場合どのように実装するのが正しいのでしょうか。教えていただきたいです。
現状のコードは以下です。CGImageDestinationCreateWithURLメソッドを使っているので既存の画像と現在地の位置情報を使って新しく画像を作成し保存してしまっています。新しく画像を保存せずに選択された画像の位置情報を書き換えて上書き保存したいです。

swift

1 2 3func selectedPhoto(picker: TLPhotosPickerViewController, at: Int) { 4 5 if self.isUsedCamera { 6 guard let asset = picker.selectedAssets[at - 1].phAsset else { fatalError() } 7 if !asset.canPerform(.content) { fatalError() } 8 let changesBlock: () -> Void = { 9 // ここPHAssetに関する処理 10 let request = PHAssetChangeRequest(for: asset) 11 LocationService.sharedInstance.startUpdatingLocation() 12 let location = LocationService.sharedInstance.location! 13 14 request.location = location 15 } 16 PHPhotoLibrary.shared().performChanges(changesBlock) { (status, error) in 17 // statusはカメラで撮影した画像かライブラリから選択した画像かを判別するフラグ 18 if status { 19 let result = PHAsset.fetchAssets(withLocalIdentifiers: [asset.localIdentifier], options: nil) 20 // PHAsset書き換え後のassetを再取得 21 guard let afterAsset = result.firstObject else { fatalError() } 22 // 画像自体のExif情報を書き換える 23 let options = PHImageRequestOptions() 24 options.isSynchronous = false 25 options.isNetworkAccessAllowed = true 26 options.deliveryMode = .opportunistic 27 options.version = .current 28 options.resizeMode = .exact 29 options.progressHandler = { (progress, error, stop, info) in 30 // progressBlock(progress) 31 } 32 let _ = PHCachingImageManager().requestImageData(for: asset, options: options) { (imageData, dataUTI, orientation, info) in 33 if let data = imageData { 34 35 guard let image = CIImage(data: data) else { fatalError() } 36 var meta:NSMutableDictionary? 37 if let location = LocationService.sharedInstance.location { 38 meta = LocationService.sharedInstance.setMeta(location) 39 } 40 afterAsset.requestContentEditingInput(with: PHContentEditingInputRequestOptions()) { (input, _) in 41 guard let tmpUrl = input?.fullSizeImageURL else { return } 42 if let dest = CGImageDestinationCreateWithURL(tmpUrl as CFURL, kUTTypeJPEG, 1, nil) { 43 let ctx = CIContext() 44 let cgimage = ctx.createCGImage(image, from: image.extent)! 45 CGImageDestinationAddImage(dest, cgimage, meta) 46 CGImageDestinationFinalize(dest) 47 PHPhotoLibrary.shared() 48 .performChanges({ PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: tmpUrl as URL) }, 49 completionHandler: { success, error in 50 if success { 51 self.latitude = LocationService.sharedInstance.latitude 52 self.longitude = LocationService.sharedInstance.longitude 53 DispatchQueue.main.async { 54 print("保存できました") 55 } 56 } else { 57 print("保存出来ませんでした。修正する所がないか確認してください。") 58 } 59 }) 60 } 61 } 62 63 64 } 65 } 66 } else { 67 fatalError(String(describing: error!.localizedDescription)) 68 } 69 } 70 self.isUsedCamera = false 71 } else { 72 if !(picker.selectedAssets.isEmpty) { 73 // print("picker.selectedAssets[0].phAsset!.location: (picker.selectedAssets[at - 1].phAsset!.location)") 74 } 75 76 77 } 78} 79

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問