Reputation: 1247
I am trying to write gps coordinates to an image that is taken within my app. So i looked around for code to use, and i wrote a function that takes Data
and also returns Data
(since i need to send it like this to Firebase
.
But no matter how i seem to write this code the metadata won't "stick" to the picture. The picture looks correct when it uploads, but upon download it doesn't contain any more metadata than the size of the photo.
Have I totally missed out on something here?
func setMetaData(imageData: Data) -> Data? {
var source: CGImageSource? = nil
source = CGImageSourceCreateWithData((imageData as CFData?)!, nil)
let metadata = CGImageSourceCopyPropertiesAtIndex(source!, 0, nil) as? [AnyHashable: Any]
var metadataAsMutable = metadata
var EXIFDictionary = (metadataAsMutable?[(kCGImagePropertyExifDictionary as String)]) as? [AnyHashable: Any]
var GPSDictionary = (metadataAsMutable?[(kCGImagePropertyGPSDictionary as String)]) as? [AnyHashable: Any]
if !(EXIFDictionary != nil) {
EXIFDictionary = [AnyHashable: Any]()
}
if !(GPSDictionary != nil) {
GPSDictionary = [AnyHashable: Any]()
}
GPSDictionary![(kCGImagePropertyGPSLatitude as String)] = 30.21313
GPSDictionary![(kCGImagePropertyGPSLongitude as String)] = 76.22346
let dest_data = NSMutableData()
guard let imageDest = CGImageDestinationCreateWithData(dest_data as CFMutableData, kUTTypeJPEG, 1, nil) else { return nil }
CGImageDestinationAddImageFromSource(imageDest, source!, 0, (metadataAsMutable as CFDictionary?))
if CGImageDestinationFinalize(imageDest) {
return dest_data as Data
} else {
print("FAILED")
}
return nil
}
Upvotes: 1
Views: 2098
Reputation: 1247
I found a solution that's not super pretty, but it totally does the job
func addMetaData(data: Data) -> NSData? {
guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {return nil}
guard let type = CGImageSourceGetType(source) else {return nil}
let mutableData = NSMutableData(data: data)
guard let destination = CGImageDestinationCreateWithData(mutableData, type, 1, nil) else {
return nil}
guard let path = Bundle.main.url(forResource: "predict_pic", withExtension: "jpg") else {
return nil }
let imageSource = CGImageSourceCreateWithURL(path as CFURL, nil)
let imageProperties = CGImageSourceCopyMetadataAtIndex(imageSource!, 0, nil)
let mutableMetadata = CGImageMetadataCreateMutableCopy(imageProperties!)
CGImageMetadataSetValueMatchingImageProperty(mutableMetadata!, kCGImagePropertyGPSDictionary, kCGImagePropertyGPSLatitudeRef, "N" as CFTypeRef)
CGImageMetadataSetValueMatchingImageProperty(mutableMetadata!, kCGImagePropertyGPSDictionary, kCGImagePropertyGPSLatitude, location.coordinate.latitude as CFTypeRef)
CGImageMetadataSetValueMatchingImageProperty(mutableMetadata!, kCGImagePropertyGPSDictionary, kCGImagePropertyGPSLongitudeRef, "E" as CFTypeRef)
CGImageMetadataSetValueMatchingImageProperty(mutableMetadata!, kCGImagePropertyGPSDictionary, kCGImagePropertyGPSLongitude, location.coordinate.longitude as CFTypeRef)
let finalMetadata:CGImageMetadata = mutableMetadata!
CGImageDestinationAddImageAndMetadata(destination, UIImage(data: data)!.cgImage! , finalMetadata, nil)
guard CGImageDestinationFinalize(destination) else { return nil }
return mutableData;
}
Upvotes: 2