我正在使用PhotoKit编辑照片,我需要保留原始照片中的元数据。为此,我保存元数据,然后将其提供给options
中的CGImageDestinationAddImage
参数。我能够最终确定它并将其成功写入磁盘,但是当我调用performChanges
提交资产编辑时,它会失败。如果我为nil
提供options
,它就会成功。这里出了什么问题?
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
})
}
}
})
错误是:Error Domain=NSCocoaErrorDomain Code=-1 "The operation couldn’t be completed. (Cocoa error -1.)
答案 0 :(得分:1)
为了编辑照片,似乎必须填写adjustementData
对象的PHContentEditingOutput
属性。
答案 1 :(得分:1)
元数据中的某些键似乎会导致失败。这有效:
NSArray *validMetadataKeys = @[
(NSString *)kCGImagePropertyTIFFDictionary,
(NSString *)kCGImagePropertyGIFDictionary,
(NSString *)kCGImagePropertyJFIFDictionary,
(NSString *)kCGImagePropertyExifDictionary,
(NSString *)kCGImagePropertyPNGDictionary,
(NSString *)kCGImagePropertyIPTCDictionary,
(NSString *)kCGImagePropertyGPSDictionary,
(NSString *)kCGImagePropertyRawDictionary,
(NSString *)kCGImagePropertyCIFFDictionary,
(NSString *)kCGImageProperty8BIMDictionary,
(NSString *)kCGImagePropertyDNGDictionary,
(NSString *)kCGImagePropertyExifAuxDictionary,
];
NSMutableDictionary *validMetadata = [NSMutableDictionary dictionary];
[metadata enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([validMetadataKeys containsObject:key]) {
validMetadata[key] = obj;
}
}];
// your CGImage stuff
CGImageDestinationAddImageFromSource(destination, imgSource, 0, (__bridge CFDictionaryRef)validMetadata);
答案 2 :(得分:1)
我有完全相同的问题,我已提交雷达rdar:// 21057247。我尝试使用TSI记录案例,但我被告知要提交雷达。
答案 3 :(得分:0)
//如果资产不允许所请求的更改类型,这些方法将引发异常,在资产上调用canPerformEditOperation:以确定是否允许编辑操作的类型。
我认为这是因为Apple不希望您更改metaData。您可以尝试以下方法,也许可以创建一个新方法。
答案 4 :(得分:0)
我们应该将新图像的数据写入我们通过
获取的URL let theExportURL = output.renderedContentURL
就我而言,我这样做......
let outputData = UIImagePNGRepresentation(bakedImage)
在运行时我收到了错误
Error Domain=NSCocoaErrorDomain Code=-1 "The operation couldn’t be completed. (Cocoa error -1.)
但是当我开始导出这样的数据时......
let outputData = UIImageJPEGRepresentation(bakedImage, 1)
有效。这里记录了...... https://developer.apple.com/library/prerelease/ios/documentation/Photos/Reference/PHContentEditingOutput_Class/index.html
这个问题在这里得到了回答...... https://stackoverflow.com/a/28362235