I am using PhotoKit to edit photos and I need to preserve the metadata from the original photo. To do so I save the metadata then provide it to the options
parameter in CGImageDestinationAddImage
. I am able to finalize it and write it to disk successfully, but when I call performChanges
to commit the asset edit, it fails. If I instead provide nil
for options
it will succeed. What is going wrong here?
asset.requestContentEditingInputWithOptions(options) { (input: PHContentEditingInput!, _) -> Void in
//get full image
let url = input.fullSizeImageURL
let inputImage = CIImage(contentsOfURL: url)
//get orginal photo's metadata
let originalImageData = NSData(contentsOfURL: url)!
let imageSource = CGImageSourceCreateWithData(originalImageData, nil)
let metadata: CFDictionaryRef = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)
println(metadata) //prints all the metadata, yay!
//do some processing on original photo here and create an output CIImage...
//save to disk
let dataRef = CFDataCreateMutable(nil, 0)
let destination = CGImageDestinationCreateWithData(dataRef, CGImageSourceGetType(imageSource), 1, nil)
let eaglContext = EAGLContext(API: .OpenGLES2)
let ciContext = CIContext(EAGLContext: eaglContext)
let cgImage = ContextStruct.ciContext!.createCGImage(outputPhoto, fromRect: outputPhoto.extent())
CGImageDestinationAddImage(destination, cgImage, metadata) //metadata is problematic - replacing with nil causes it to work
if CGImageDestinationFinalize(destination) {
let contentEditingOutput = PHContentEditingOutput(contentEditingInput: input)
contentEditingOutput.adjustmentData = "something"
let imageData: NSData = dataRef
let success = imageData.writeToURL(contentEditingOutput.renderedContentURL, options: .AtomicWrite, error: _)
if success {
PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in
let request = PHAssetChangeRequest(forAsset: asset)
request.contentEditingOutput = contentEditingOutput
}, completionHandler: { (success: Bool, error: NSError!) -> Void in
if success == false { println('failed to commit image edit: \(error)') } //fails unless metadata is replaced with nil above
})
}
}
})
The error is: Error Domain=NSCocoaErrorDomain Code=-1 "The operation couldn’t be completed. (Cocoa error -1.)
We are supposed to write the data for the new image to the URL we obtain via
In my case i was doing this...
And at runtime i was getting the error
But when I started exporting the data like this...
It worked. This is documented here ... https://developer.apple.com/library/prerelease/ios/documentation/Photos/Reference/PHContentEditingOutput_Class/index.html
and this same question has been answered here... https://stackoverflow.com/a/28362235
// if the asset does not allow the type of change requested, these methods will raise an exception, call canPerformEditOperation: on the asset to determine if the type of edit operation is allowed.
I think it's because Apple don't want you to change the metaData.You can try this method below,maybe create a new one is allowed.
Certain keys in the metadata seem to cause failure. This works:
I have exactly the same problem, and I have filed a radar rdar://21057247. I try to log a case using TSI but I have been told to file a radar instead.
It seems that filling the
adjustementData
property of thePHContentEditingOutput
object is mandatory in order to edit a photo.