如何从 PhotosPicker 检索 CLLocation

问题描述 投票:0回答:1

我注意到,当显示照片选择器时,底部会显示“包含位置”,并且“选项”菜单允许用户将其关闭。

我们如何检查从以下位置获取照片时是否提供了选项菜单中包含的 CLLocation 或标题:

PhotosPicker(selection: $selectedItem, matching: .images, photoLibrary: .shared()) {
                    
                    Text("Open Photo Picker")
                    
                }
                .onChange(of: selectedItem) { newItem in
                                
                    if let selected = newItem {
                        // Have PhotosPickerItem, now how to get CLLocation?
                    }
                               
                }

这是访问元数据/GPS 信息的唯一方法吗? 无需通过请求许可来访问 PHAsset?

swiftui photospicker
1个回答
0
投票

这个答案,您需要做的就是

  • PhotosPickerItem
    加载为
    Data
  • 从数据创建
    CGImageSource
  • CGImageSource
  • 获取元数据

所以

@State var selection: PhotosPickerItem?
var body: some View {
    PhotosPicker("Pick", selection: $selection)
        .task(id: selection) {
            guard let data = try? await selection?.loadTransferable(type: Data.self),
                  let src = CGImageSourceCreateWithData(data as CFData, nil),
                  let metadata = CGImageSourceCopyPropertiesAtIndex(src,0,nil) else {
                return
            }
            print(metadata) // metadata is a CFDictionary
        }
}

位置信息和标题都在元数据字典中。字典的键都在here小节中列出。

kCGImagePropertyGPSDictionary
键下存储的位置信息,它本身就是另一个字典。纬度、经度、海拔、速度等有不同的按键。

这里我编写了一个函数,以

CLLocationCoordinate2D
:

的形式获取位置
func coordinates(from metadata: CFDictionary) -> CLLocationCoordinate2D? {
    guard let dict = metadata as? [AnyHashable: Any],
          let gpsDict = dict[kCGImagePropertyGPSDictionary] as? [AnyHashable: Any],
          let lat = gpsDict[kCGImagePropertyGPSLatitude] as? Double,
          let lon = gpsDict[kCGImagePropertyGPSLongitude] as? Double,
          let latRef = gpsDict[kCGImagePropertyGPSLatitudeRef] as? String,
          let lonRef = gpsDict[kCGImagePropertyGPSLongitudeRef] as? String
        else { return nil }
    return CLLocationCoordinate2D(
        latitude: latRef == "N" ? lat : -lat,
        longitude: lonRef == "E" ? lon : -lon
    )
}

我找到了两个存储标题的地方。

  • 在字典中按
    kCGImagePropertyTIFFDictionary
    键,然后按该字典的
    kCGImagePropertyTIFFImageDescription
    键。
  • 在字典中的
    kCGImagePropertyIPTCDictionary
    键下。然后是该字典的
    kCGImagePropertyIPTCCaptionAbstract
    键。
© www.soinside.com 2019 - 2024. All rights reserved.