Skip to content

Instantly share code, notes, and snippets.

@lacyrhoades
Last active March 24, 2023 04:54
Show Gist options
  • Save lacyrhoades/09d8a367125b6225df5038aec68ed9e7 to your computer and use it in GitHub Desktop.
Save lacyrhoades/09d8a367125b6225df5038aec68ed9e7 to your computer and use it in GitHub Desktop.
import UIKit
import MobileCoreServices
import ImageIO
let sourceOptions: [String: AnyObject] = [kCGImageSourceTypeIdentifierHint as String: kUTTypeJPEG]
let cfSourceOptions = sourceOptions as CFDictionary
let image = UIImage(named: "input.jpg")!
let data = UIImageJPEGRepresentation(image, 1.0)
let source: CGImageSource = CGImageSourceCreateWithData(data as! CFData, cfSourceOptions)!
let filepath = NSTemporaryDirectory().appending("out.jpg")
print("Output file:")
print(filepath)
let fileURL: URL = URL(fileURLWithPath: filepath)
let destination: CGImageDestination = CGImageDestinationCreateWithURL(fileURL as CFURL, kUTTypeJPEG, 1, nil)!
var makeTag = CGImageMetadataTagCreate(
kCGImageMetadataNamespaceTIFF, kCGImageMetadataPrefixTIFF, kCGImagePropertyTIFFMake, .string, "Make" as CFString
)!
var modelTag = CGImageMetadataTagCreate(
kCGImageMetadataNamespaceTIFF, kCGImageMetadataPrefixTIFF, kCGImagePropertyTIFFModel, .string, "Model" as CFString
)!
var metaDatas = CGImageMetadataCreateMutable()
var tagPath = "tiff:Make" as CFString
var result = CGImageMetadataSetTagWithPath(metaDatas, nil, tagPath, makeTag)
tagPath = "tiff:Model" as CFString
result = CGImageMetadataSetTagWithPath(metaDatas, nil, tagPath, modelTag)
let destOptions: [String: AnyObject] = [
kCGImageDestinationMergeMetadata as String: NSNumber(value: 1),
kCGImageDestinationMetadata as String: metaDatas
]
let cfDestOptions = destOptions as CFDictionary
var error: Unmanaged<CFError>?
var errorPtr: UnsafeMutablePointer<CFError>
withUnsafeMutablePointer(to: &error, { ptr in
result = CGImageDestinationCopyImageSource(destination, source, cfDestOptions, ptr)
print(String(format: "Write image to file result: %@", result ? "Success" : "Failed"))
print(String(format: "With error: %@", error.debugDescription))
})
let writeResult = CGImageDestinationFinalize(destination)
// This is false, and you may see an error like:
// " ImageIO: finalize:2031: not allowed for image destination that was updated with CGImageDestinationCopyImageSource "
// But, in practice, it works. The file is there and the metadata is correct.
print(writeResult)
@lacyrhoades
Copy link
Author

@maurymarkowitz no idea about errorPtr I ended up not having that line in production. Thanks for the tips too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment