ユーザーが PhotoKit を使用して写真を編集できるアプリを開発しています。以前は、編集した写真を JPEG としてディスクに保存していました。JPEG への変換を避けたいので、そのための変更を実装しました。カメラで撮影した写真には最適ですが、スクリーンショットを編集しようとすると、PHPhotoLibrary.sharedPhotoLibrary().performChanges
ブロックが失敗してログに記録されますThe operation couldn’t be completed. (Cocoa error -1.)
。これが原因で performChanges ブロックが失敗する理由がわかりません。ここで何が間違っているのでしょうか?
問題を示すダウンロード可能なサンプル アプリを作成し、以下に関連するコードを含めました。アプリは、フォト ライブラリの最新の写真を編集しようとします。成功すると、写真を編集するためのアクセスを求められます。それ以外の場合は何も起こらず、コンソール ログが表示されます。問題を再現するには、スクリーンショットを撮り、アプリを実行します。
スクリーンショットで動作する現在のコード:
let jpegData: NSData = outputPhoto.jpegRepresentationWithCompressionQuality(0.9)
let contentEditingOutput = PHContentEditingOutput(contentEditingInput: self.input)
var error: NSError?
let success = jpegData.writeToURL(contentEditingOutput.renderedContentURL, options: NSDataWritingOptions.AtomicWrite, error: &error)
if success {
return contentEditingOutput
} else {
return nil
}
スクリーンショットが失敗する原因となる代替コード:
let url = self.input.fullSizeImageURL
let orientation = self.input.fullSizeImageOrientation
var inputImage = CIImage(contentsOfURL: url)
inputImage = inputImage.imageByApplyingOrientation(orientation)
let outputPhoto = createOutputImageFromInputImage(inputImage)!
let originalImageData = NSData(contentsOfURL: self.input.fullSizeImageURL)!
let imageSource = CGImageSourceCreateWithData(originalImageData, nil)
let dataRef = CFDataCreateMutable(nil, 0)
let destination = CGImageDestinationCreateWithData(dataRef, CGImageSourceGetType(imageSource), 1, nil) //getType automatically selects JPG, PNG, etc based on original format
struct ContextStruct {
static var ciContext: CIContext? = nil
}
if ContextStruct.ciContext == nil {
let eaglContext = EAGLContext(API: .OpenGLES2)
ContextStruct.ciContext = CIContext(EAGLContext: eaglContext)
}
let cgImage = ContextStruct.ciContext!.createCGImage(outputPhoto, fromRect: outputPhoto.extent())
CGImageDestinationAddImage(destination, cgImage, nil)
if CGImageDestinationFinalize(destination) {
let contentEditingOutput = PHContentEditingOutput(contentEditingInput: self.input)
var error: NSError?
let imageData: NSData = dataRef
let success = imageData.writeToURL(contentEditingOutput.renderedContentURL, options: .AtomicWrite, error: &error)
if success {
//it does succeed
return contentEditingOutput
} else {
return nil
}
}