21

I am trying to write EXIF data to the image but CGImageDestinationFinalize crashes:

var image = info[UIImagePickerControllerOriginalImage] as! UIImage
    let jpeg = UIImageJPEGRepresentation(image, 1.0)
    var source: CGImageSource? = nil
    source = CGImageSourceCreateWithData((jpeg 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]

    GPSDictionary![(kCGImagePropertyGPSLatitude as String)] = 30.21313
    GPSDictionary![(kCGImagePropertyGPSLongitude as String)] = 76.22346
    EXIFDictionary![(kCGImagePropertyExifUserComment as String)] = "Hello Image"


let UTI: CFString = CGImageSourceGetType(source!)!
    let dest_data = NSMutableData()
    let destination: CGImageDestination = CGImageDestinationCreateWithData(dest_data as CFMutableData, UTI, 1, nil)!
    CGImageDestinationAddImageFromSource(destination, source!, 0, (metadataAsMutable as CFDictionary?))
    CGImageDestinationFinalize(destination)
Inderpal Singh
  • 1,229
  • 2
  • 10
  • 13
  • Please show some more information about the crash. – Andreas Oetjen Mar 21 '18 at 09:46
  • 1
    Crash log please! – TheTiger Mar 21 '18 at 10:07
  • This code worked for me. – Lenin Mar 24 '18 at 08:09
  • @Lenin How do you save the image (with the exif data) into a file? – niczm25 Nov 28 '18 at 12:03
  • @niczm25 Check this let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) let fileURL = documentsDirectoryURL.appendingPathComponent("fileName") if !FileManager.default.fileExists(atPath: fileURL.path) { do { try dest_data.write(to: fileURL) } catch { print(error.localizedDescription) } } else { } – Inderpal Singh Nov 28 '18 at 12:08

2 Answers2

14

Please check this below answer. you got error due to nil value on EXIFDictionary and GPSDictionary

 var image = info[UIImagePickerControllerOriginalImage] as! UIImage
 let jpeg = UIImageJPEGRepresentation(image, 1.0)
 var source: CGImageSource? = nil
 source = CGImageSourceCreateWithData((jpeg 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
   EXIFDictionary![(kCGImagePropertyExifUserComment as String)] = "Hello Image"

   let UTI: CFString = CGImageSourceGetType(source!)!
   let dest_data = NSMutableData()
   let destination: CGImageDestination = CGImageDestinationCreateWithData(dest_data as CFMutableData, UTI, 1, nil)!
   CGImageDestinationAddImageFromSource(destination, source!, 0, (metadataAsMutable as CFDictionary?))
            CGImageDestinationFinalize(destination)
Inder_iOS
  • 1,636
  • 1
  • 12
  • 20
1

This could be from your destination definition.

This worked for me

(...)
    let source                  =   CGImageSourceCreateWithData(jpgData as CFData, nil)

    let finalData               =   NSMutableData()

    let destination             =   getDestination(finalData:finalData, source:source!)

(...)

// Note that :
// NSMutableData type variable will be cast to CFMutableData
// 
fileprivate func getDestination(finalData:CFMutableData, source:CGImageSource)->CGImageDestination?{
    guard let destination = CGImageDestinationCreateWithData(finalData,
                                                             CGImageSourceGetType(source)!,
                                                             1,
                                                             nil)else{return nil}
    return destination
}
Jan ATAC
  • 1,212
  • 1
  • 18
  • 36