4

PhotoKit を使用して写真を編集していますが、元の写真のメタデータを保持する必要があります。そのために、メタデータを保存し、それを のoptionsパラメーターに提供しますCGImageDestinationAddImage。ファイナライズしてディスクに正常に書き込むことはできますが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

私はまったく同じ問題を抱えており、レーダー rdar://21057247 を提出しました。TSI を使用して事件を記録しようとしましたが、代わりにレーダーを提出するように言われました。

于 2015-05-21T15:40:38.813 に答える
1

adjustementData写真を編集するには、オブジェクトのプロパティを埋めることPHContentEditingOutputが必須のようです。

于 2015-02-01T20:32:04.147 に答える
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 に答える
0

// リクエストされた変更のタイプがアセットで許可されていない場合、これらのメソッドは例外を発生させ、アセットで canPerformEditOperation: を呼び出して、編集操作のタイプが許可されているかどうかを判断します。

  • (インスタンスタイプ)changeRequestForAsset:(PHAsset *)asset;

これは、Apple がメタデータの変更を望んでいないためだと思います。以下でこの方法を試すことができます。新しい方法を作成することもできます。

  • (インスタンスタイプ)creationRequestForAssetFromImage:(UIImage *)image;
  • (インスタンスタイプ)creationRequestForAssetFromImageAtFileURL:(NSURL *)fileURL;
  • (インスタンスタイプ)creationRequestForAssetFromVideoAtFileURL:(NSURL *)fileURL;
于 2015-05-29T07:45:18.610 に答える