Some EXIF entries require float content as a string. For example FNumber often looks like that: "2.8" or "1.4". When I edit EXIF data using CGImageDestinationCopyImageSource most of the EXIF entries that require that float-like content are truncated to their first character. To stay in the example above the EXIF dict will be written with a "2" or "1". The dot and the rest of the string are truncated. 🤯
Shall: "2.8" Is: "2"
All EXIF data is written correctly (I use about 40 fields), but only the following keys are reduced to some kind of integer style:
- kCGImagePropertyExifFNumber
- kCGImagePropertyExifFocalLength
- kCGImagePropertyGPSAltitude
- kCGImagePropertyGPSImgDirection
- kCGImagePropertyGPSSpeed
I am using this code to set the entries:
let metaData = CGImageMetadataCreateMutable()
if !CGImageMetadataSetValueMatchingImageProperty(metaData, kCGImagePropertyExifDictionary, kCGImagePropertyExifFNumber, 2.8 as CFTypeRef) {
print("kCGImagePropertyExifFNumber EXIF not written")
}
let destOptions: [String: AnyObject] = [
kCGImageDestinationMergeMetadata as String: NSNumber(value: 1),
kCGImageDestinationMetadata as String: metaData
]
if !CGImageDestinationCopyImageSource(destination, cgImgSource, destOptions as CFDictionary, nil) {
print("Error making CGImageDestinationCopyImageSource")
}
The dictionary being created shows me the correct values, but when I open the updated JPG, I only see the truncated floating point numbers.
I tried it with
- 2.8 as CFString
- "2.8" as CFString
- 2.8 as CFTypeRef
- "2.8" as CFTypeRef
- 2.8 as CFNumber
- 2.8 as NSNumber
- 2.8 as NSString
Only in kCGImagePropertyGPSLongitude & kCGImagePropertyGPSLatitude this behavior doesn't occur.
if !CGImageMetadataSetValueMatchingImageProperty(metaData, kCGImagePropertyGPSDictionary, kCGImagePropertyGPSLatitude, 53.997853 as CFTypeRef ) {
print("kCGImagePropertyGPSLatitude GPS not written")
}
Using CGImageDestinationCreateWithData does not do this and writes the data correctly.
I think that’s strange, because most photos aren’t taken with int-values. So either I found a bug or I am doing something wrong. What’s the point here? Is there some kind of round-rule?