2015-02-01 3 views
4

PhotoKit을 사용하여 사진을 편집하고 원본 사진의 메타 데이터를 보존해야합니다. 그렇게하려면 메타 데이터를 저장 한 다음 options 매개 변수 CGImageDestinationAddImage에 제공하십시오. 마무리하고 디스크에 성공적으로 쓸 수 있지만 performChanges을 호출하여 자산 편집을 커밋하면 실패합니다. optionsnil을 입력하면 성공합니다. 여기서 뭐가 잘못 됐어?이미지에 메타 데이터를 적용하면 performChanges 요청이 실패합니다.

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

나는 동일한 오류로 실행 한 ... 여기에 답하고있다. 사과에 열린 버그가 있습니까? – Glavid

+0

@ 그래 비드 예, 그걸 들었습니다. 자신의 보고서를 작성하고 아무 것도 들리지 않으면 다시보고하십시오. – Joey

+0

을 사용할 수 있습니다. Thanks – Glavid

답변

0

PHContentEditingOutput 개체의 adjustementData 속성을 작성하여 사진을 편집하기 위해서는 필수입니다 것으로 보인다.

+0

실제로'adjustmentData'를 설정하고 있는데, 위 코드의 내용을 그대로 두었습니다. 그래서 좀 더 간결하지만 한 줄에 추가했습니다. – Joey

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); 
+0

적어도 전환을 잘못했을 때를 제외하고는 Swift를 사용할 때 여전히 performChanges가 실패합니다. – Joey

1

내가 정확히 같은 문제가 있고, 나는 레이다 rdar : // 21057247을 제기했다. 나는 TSI를 사용하여 사건을 기록하려하지만 대신에 레이다를 신고하라는 말을 들었다.

0

// 자산이 요청 된 변경 유형을 허용하지 않는 경우 이러한 메소드는 예외를 발생시키고 자산에 대해 canPerformEditOperation :을 호출하여 편집 작업의 유형이 허용되는지 여부를 결정합니다.

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

나는 애플이 당신이 메타 데이터를 변경하기를 원하지 않기 때문이라고 생각한다.이 방법을 아래에서 시도해 볼 수있다. 아마도 새로운 것을 만들 수있다.

  • (instancetype) creationRequestForAssetFromImage : (UIImage *) image;
  • (instancetype) creationRequestForAssetFromImageAtFileURL : (NSURL *) fileURL;
  • (instancetype) creationRequestForAssetFromVideoAtFileURL : (NSURL *) fileURL;
0

우리는 ...

   let outputData = UIImagePNGRepresentation(bakedImage) 

그리고 런타임에 우리가 내 경우

   let theExportURL = output.renderedContentURL 

내가이 일을했다 통해 얻을 URL에 새 이미지에 대한 데이터를 쓰기로되어있다 오류가 발생했습니다

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

관련 문제