7

ユーザーが 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
     }
}
4

1 に答える 1

0

この問題は、調整された写真が常に JPG ファイルとして保存され、スクリーンショットが実際には PNG ファイルであるために発生します。

サンプル プロジェクトをデバッグしているときに、PhotoEditor で見たのはcontentEditingOutput.renderedContentURLJPG への URL ですが、その結果を調べると、CGImageSourceGetType(imageSource)それが PNG であることが明らかです (PNG UTI: public.png を返します)。

そこで、写真アセットを編集すると、変更された画像が JPEG 形式で書き込まれると記載されているドキュメントを読みましたrenderedContentURL。これは、画像が PNG の場合は明らかに機能しません。このことから、Apple は PNG ファイルの編集をサポートしていないか、サポートしたくないと考えています。図に行く..

于 2015-06-12T20:54:33.877 に答える