2015-02-01 6 views
4

Я использую 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

Я побежал в ту же ошибку. Есть ли ошибка с яблоком? – Glavid

+0

@ Glavid Да, они не слышали от них. Пожалуйста, напишите свой собственный отчет и сообщите, если вы что-нибудь услышите. – Joey

+0

сделаю. Спасибо – Glavid

ответ

0

Кажется, что заполнение adjustementData свойства PHContentEditingOutput объекта является обязательным для редактирования фото.

+0

На самом деле я устанавливаю 'adjustData', я просто оставил это в коде выше, чтобы он был более кратким, но это одна строка, поэтому я добавил его. – 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

Это все еще приводит к сбою 'performChanges', по крайней мере, при использовании Swift, если только я не сделал что-то неправильное в преобразовании. – Joey

1

У меня точно такая же проблема, и я подал радиолокационную rdar: // 21057247. Я пытаюсь зарегистрировать случай с использованием TSI, но мне сказали, чтобы он использовал вместо него радар.

0

// Если ресурс не разрешает запрашиваемый тип изменения, эти методы будут создавать исключение, вызовите canPerformEditOperation: на актив, чтобы определить, разрешен ли тип операции редактирования.

  • (instancetype) changeRequestForAsset: (PHAsset *) актив;

Я думаю, это потому, что Apple не хочет, чтобы вы меняли метаданные. Вы можете попробовать этот метод ниже, возможно, создать новый.

  • (instancetype) созданиеRequestForAssetFromImage: (UIImage *) изображение;
  • (instancetype) созданиеRequestForAssetFromImageAtFileURL: (NSURL *) fileURL;
  • (instancetype) созданиеRequestForAssetFromVideoAtFileURL: (NSURL *) файлURL;
0

Мы должны написать данные для нового изображения в URL мы получаем через

   let theExportURL = output.renderedContentURL 

В моем случае я делал это ...

   let outputData = UIImagePNGRepresentation(bakedImage) 

И во время выполнения я получал ошибку

Error Domain=NSCocoaErrorDomain Code=-1 "The operation couldn’t be completed. (Cocoa error -1.) 

Но когда я начал экспортировать данные li ke это ...

let outputData = UIImageJPEGRepresentation(bakedImage, 1) 

Это сработало. Это описано здесь ... https://developer.apple.com/library/prerelease/ios/documentation/Photos/Reference/PHContentEditingOutput_Class/index.html

и этот же вопрос был дан ответ здесь ... https://stackoverflow.com/a/28362235

 Смежные вопросы

  • Нет связанных вопросов^_^