如何使用AVCapturePhoto包含位置数据?

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

我正在尝试在Swift中编写一个iOS应用程序,让用户拍照,然后我将在图像上叠加一些额外的数据。我希望图像包含位置数据。我正在使用AVCapturePhoto,我可以在文档中看到它有一些元数据变量,但我找不到有关如何使用它们的任何信息。当我现在使用我的应用拍摄照片时,它在EXIF信息中没有位置数据。

如何设置捕获会话以嵌入位置数据?

ios swift xcode avfoundation cllocationmanager
1个回答
3
投票

我还没有处理新的IOS 11 AVCapturePhoto对象,因此这个答案必须对如何访问数据做出一些假设,但理论上所有这些都应该有效。

在添加位置数据之前,您需要询问用户是否可以使用他们的位置。在您的Info.plist中添加“隐私 - 使用中的位置”标签。然后在初始化的某处添加以下代码。

// Request authorization for location manager 
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
    break

case .notDetermined:
    locationManager.requestWhenInUseAuthorization()
    locationManagerStatus = CLLocationManager.authorizationStatus()

default:
    locationManagerStatus = .denied
}

现在,以下内容将创建一个包含位置信息的字典。

// create GPS metadata properties
func createLocationMetadata() -> NSMutableDictionary? {

    guard CLLocationManager.authorizationStatus() == .authorizedWhenInUse else {return nil}

    if let location = locationManager.location {
        let gpsDictionary = NSMutableDictionary()
        var latitude = location.coordinate.latitude
        var longitude = location.coordinate.longitude
        var altitude = location.altitude
        var latitudeRef = "N"
        var longitudeRef = "E"
        var altitudeRef = 0

        if latitude < 0.0 {
            latitude = -latitude
            latitudeRef = "S"
        }

        if longitude < 0.0 {
            longitude = -longitude
            longitudeRef = "W"
        }

        if altitude < 0.0 {
            altitude = -altitude
            altitudeRef = 1
        }

        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy:MM:dd"
        gpsDictionary[kCGImagePropertyGPSDateStamp] = formatter.string(from:location.timestamp)
        formatter.dateFormat = "HH:mm:ss"
        gpsDictionary[kCGImagePropertyGPSTimeStamp] = formatter.string(from:location.timestamp)
        gpsDictionary[kCGImagePropertyGPSLatitudeRef] = latitudeRef
        gpsDictionary[kCGImagePropertyGPSLatitude] = latitude
        gpsDictionary[kCGImagePropertyGPSLongitudeRef] = longitudeRef
        gpsDictionary[kCGImagePropertyGPSLongitude] = longitude
        gpsDictionary[kCGImagePropertyGPSDOP] = location.horizontalAccuracy
        gpsDictionary[kCGImagePropertyGPSAltitudeRef] = altitudeRef
        gpsDictionary[kCGImagePropertyGPSAltitude] = altitude

        if let heading = locationManager.heading {
            gpsDictionary[kCGImagePropertyGPSImgDirectionRef] = "T"
            gpsDictionary[kCGImagePropertyGPSImgDirection] = heading.trueHeading
        }

        return gpsDictionary;
    }
    return nil
}

这是我必须做一些猜测的地方,因为我没有处理过IOS 11 AVPhotoCapture。您将需要图像数据的文件数据表示。我假设

AVCapturePhoto.fileDataRepresentation() 

返回此。您还需要原始文件元数据。我会猜测一下

AVCapturePhoto.metadata

包含这个。通过这些假设,以下函数将为您提供包含其他位置数据的文件数据表示。可能有更新的IOS 11方法以更清洁的方式执行此操作。

func getFileRepresentationWithLocationData(photo : AVCapturePhoto) -> Data {
    // get image metadata
    var properties = photo.metadata

    // add gps data to metadata
    if let gpsDictionary = createLocationMetadata() {
        properties[kCGImagePropertyGPSDictionary as String] = gpsDictionary
    }

    // create new file representation with edited metadata
    return photo.fileDataRepresentation(withReplacementMetadata:properties,
        replacementEmbeddedThumbnailPhotoFormat:photo.embeddedThumbnailPhotoFormat,
        replacementEmbeddedThumbnailPixelBuffer:photo.previewPixelBuffer,
        replacementDepthData:photo.depthData)
}
© www.soinside.com 2019 - 2024. All rights reserved.