How do you set kCGImagePropertyExifUserComment on a CGImageMetadataRef?

1.4k views Asked by At

How do you set kCGImagePropertyExifUserComment on a CGImageMetadataRef in iOS? These are the only functions I have found and they are only for MacOS

https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.9.sdk/System/Library/Frameworks/ImageIO.framework/Versions/A/Headers/CGImageMetadata.h

2

There are 2 answers

4
adamfowlerphoto On

Given image data you can get it's properties with the following

func getImageDataProperties(_ data: Data) -> NSDictionary? {
    if let imageSource = CGImageSourceCreateWithData(imageData as CFData, nil) 
    {
        if let dictionary = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) {
            return dictionary
        }
    }
    return nil
}

The exif comments can be accessed as follows with the properties

if let properties = getImageDataProperties(data) {
    if let exif = properties[kCGImagePropertyExifDictionary] as? NSDictionary {
        if let comment = exif[kCGImagePropertyExifUserComment] as? String {
            ...
        }
    }
}

Once you have edited the comments you can save your image with the following given you original image data and your altered properties dictionary

// add image properties (exif, gps etc) to image
func addImageProperties(imageData: Data, properties: NSMutableDictionary) -> Data? {

    // create an imagesourceref
    if let source = CGImageSourceCreateWithData(imageData as CFData, nil) {
        // this is of type image
        if let uti = CGImageSourceGetType(source) {

            // create a new data object and write the new image into it
            let destinationData = NSMutableData()
            if let destination = CGImageDestinationCreateWithData(destinationData, uti, 1, nil) {

                // add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
                CGImageDestinationAddImageFromSource(destination, source, 0, properties)
                if CGImageDestinationFinalize(destination) == false {
                    return nil
                }
                return destinationData as Data
            }
        }
    }
    return nil
}
0
heilerich On

Create a mutable copy of the CGImageMetadataRef with CGImageMetadataCreateMutableCopy. Then set the property with

CGImageMetadataSetValueMatchingImageProperty(
    mutableCopy, 
    kCGImagePropertyExifDictionary, 
    kCGImagePropertyExifUserComment, 
    value)

where value is your comment as a CFTypeRef.