4

我正在使用 PhotoKit 来编辑照片,我需要保留原始照片中的元数据。为此,我保存元数据,然后将其提供optionsCGImageDestinationAddImage. 我能够完成它并将其成功写入磁盘,但是当我调用performChanges提交资产编辑时,它失败了。如果我改为提供niloptions会成功。这里出了什么问题?

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.)

4

5 回答 5

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);
于 2015-03-09T02:48:15.813 回答
1

为了编辑照片,似乎必须填充对象的adjustementData属性。PHContentEditingOutput

于 2015-02-01T20:32:04.147 回答
1

我有完全相同的问题,我已经提交了一个雷达 rdar://21057247。我尝试使用 TSI 记录一个案例,但我被告知改为提交雷达。

于 2015-05-21T15:40:38.813 回答
0

// 如果资产不允许请求的更改类型,这些方法将引发异常,在资产上调用 canPerformEditOperation: 以确定是否允许编辑操作的类型。

  • (instancetype)changeRequestForAsset:(PHAsset *)asset;

我认为这是因为 Apple 不希望您更改元数据。您可以在下面尝试此方法,也许允许创建一个新的。

  • (instancetype)creationRequestForAssetFromImage:(UIImage *)image;
  • (实例类型)creationRequestForAssetFromImageAtFileURL:(NSURL *)fileURL;
  • (实例类型)creationRequestForAssetFromVideoAtFileURL:(NSURL *)fileURL;
于 2015-05-29T07:45:18.610 回答
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

于 2015-08-31T20:44:05.327 回答