How to Add Properties For Image UIImagePicker Swif

2019-06-08 17:43发布

问题:

I want to capture an image and add properties longitude and latitude, i tried several times every example available on StackOverflow but doesn't work. I use UIImagePickerController to capture image and UIImageWriteToSavedPhotosAlbum to save data to album

The property must look like this

But now my image looks like this below

回答1:

I don't know about what you have tried so far and what is your requirement but according to your question here is an example of setting the location to image metadata.

After capturing the image:

/// This is Mohali location for example
let location = CLLocation(latitude: 30.7046, longitude: 76.7179)

/// It will return image metaData including location
let metaData = self.addLocation(location, toImage: image)

/// Saving the image to gallery
self.saveImage(image, withMetadata: metaData)

And here is all required methods:

func addLocation(_ location: CLLocation, toImage image: UIImage) -> Dictionary<String, Any> {

    /// Initializing the metaData dict
    var metaData: Dictionary<String, Any> = [:]

    /// Check if image already have its meta data
    if let ciImage = image.ciImage {
        metaData = ciImage.properties
    }

    /// Initializing the gpsData dict
    var gpsData: Dictionary<String, Any> = [:]

    /// Check if there is any gps information
    if let gps = metaData[kCGImagePropertyGPSDictionary as String] as? Dictionary<String, Any> {
        gpsData = gps
    }

    /// Adding all the required information to gpsData dictionary
    // #1. Data & Time
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy:MM:dd HH:mm:ss"
    let localDate = dateFormatter.string(from: location.timestamp)
    gpsData[kCGImagePropertyGPSTimeStamp as String] = localDate

    // #2. Latitude, Longitude
    var latitude  = location.coordinate.latitude
    var longitude = location.coordinate.longitude
    var latRef = ""
    var lngRef = ""
    if latitude < 0.0 {
        latitude *= -1.0
        latRef = "S"
    } else  {
        latRef = "N"
    }

    if longitude < 0.0 {
        longitude *= -1.0
        lngRef = "W"
    }
    else {
        lngRef = "E"
    }

    gpsData[kCGImagePropertyGPSLatitudeRef as String] = latRef
    gpsData[kCGImagePropertyGPSLongitudeRef as String] = lngRef
    gpsData[kCGImagePropertyGPSLatitude as String] = latitude
    gpsData[kCGImagePropertyGPSLongitude as String] = longitude

    // #3. Accuracy
    gpsData[kCGImagePropertyGPSDOP as String] = location.horizontalAccuracy

    // #4. Altitude
    gpsData[kCGImagePropertyGPSAltitude as String] = location.altitude

    /// You can add what more you want to add into gpsData and after that
    /// Add this gpsData information into metaData dictionary
    metaData[kCGImagePropertyGPSDictionary as String] = gpsData

    return metaData
}

func saveImage(_ image:UIImage, withMetadata metaData: Dictionary<String, Any>) {
    /// Creating jpgData from UIImage (1 = original quality)
    guard let jpgData = UIImageJPEGRepresentation(image, 1) else { return }

    /// Adding metaData to jpgData
    guard let source = CGImageSourceCreateWithData(jpgData as CFData, nil), let uniformTypeIdentifier = CGImageSourceGetType(source) else {
        return
    }

    let finalData = NSMutableData(data: jpgData)
    guard let destination = CGImageDestinationCreateWithData(finalData, uniformTypeIdentifier, 1, nil) else { return }
    CGImageDestinationAddImageFromSource(destination, source, 0, metaData as CFDictionary)
    guard CGImageDestinationFinalize(destination) else { return }

    /// Your destination file path
    let filePath = "\(documentsDicrectoryPath)/finalImage.jpg"

    /// Now write this image to directory
    if FileManager.default.fileExists(atPath: filePath) {
        try? FileManager.default.removeItem(atPath: filePath)
    }

    let success = FileManager.default.createFile(atPath: filePath, contents: finalData as Data, attributes: [FileAttributeKey.protectionKey : FileProtectionType.complete])
    if success {
        /// Finally Save image to Gallery
        /// Important you need PhotoGallery permission before performing below operation.
        try? PHPhotoLibrary.shared().performChangesAndWait {
            PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: URL(fileURLWithPath: filePath))
        }
    }
}

Below is the difference b/w normal and gps data image while viewing in PhotoGallery:

And in documentsDirectory if you see the image info it will look like: