10

PhotoKit で写真を編集していますが、元の写真のメタデータが保持されないことがわかりました。これは、Apple が提供する SamplePhotosApp でも、Sepia または Chrome フィルターを適用すると発生します。私の質問は、元の写真のメタデータがすべて確実に保持されるようにするにはどうすればよいですか?

元の画像のメタデータを取得する方法を発見し、そのメタデータをCIImage作成した最終版に保存できましたが、編集がコミットされるとまだ削除されています. CIImageを からにに変換CGImageする方法、またはディスクに書き込む方法に問題があるはずです。UIImageNSData

asset.requestContentEditingInputWithOptions(options) { (input: PHContentEditingInput!, _) -> Void in
    //Get full image
    let url = input.fullSizeImageURL
    let orientation = self.input.fullSizeImageOrientation
    var inputImage = CIImage(contentsOfURL: url)
    inputImage = inputImage.imageByApplyingOrientation(orientation)

    //do some processing on original photo here and create a CGImage...

    //save the original photo's metadata to a new CIImage:
    let originalMetadata = inputImage.properties()
    let newImage = CIImage(CGImage: editedCGImage, options: [kCIImageProperties: originalMetadata])

    println(newImage.properties()) //correctly prints all metadata!

    //commit changes to disk - somewhere after this line the metadata is lost
    let eaglContext = EAGLContext(API: .OpenGLES2)
    let ciContext = CIContext(EAGLContext: eaglContext)
    let outputImageRef = ciContext.createCGImage(newImage, fromRect: newImage.extent())
    let uiImage = UIImage(CGImage: outputImageRef, scale: 1.0, orientation: UIImageOrientation.Up)
    let jpegNSData = UIImageJPEGRepresentation(uiImage, 0.75)

    let contentEditingOutput = PHContentEditingOutput(contentEditingInput: input)
    let success = jpegData.writeToURL(contentEditingOutput.renderedContentURL, options: NSDataWritingOptions.AtomicWrite, error: _)

    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)') }
    })
})

オリジナル - [GPS] タブに注意してください。
元の写真のメタデータ

写真の編集後:
ここに画像の説明を入力

4

2 に答える 2

5

CIImage.properties の Apple ドキュメントによると:

CIImage オブジェクトがフィルター (またはフィルター チェーン) の出力である場合、このメソッドはフィルターの元の入力画像からメタデータを返します。

そうは言っても、ドキュメントが正しくない場合、これが私が行う方法です。

プロパティを自分で保存する必要があります。これを行うには、URL のコンテンツを NSData として読み取る必要があります。

NSURL *url = @"http://somewebsite.com/path/to/some/image.jpg";
NSData *imageData = [NSData dataWithContentsOfURL:url];
CIImage *image = [CIImage imageWithData:imageData];

// Save off the properties
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef) imageData);
NSDictionary* metadata = (__bridge NSDictionary *) CGImageSourceCopyProperties(imageSource, NULL);

// process your image
// ...
NSData *outputData = // create data from altered image.

// Save the image
CGImageSourceRef outputImageSource = CGImageSourceCreateWithData((__bridge CFDataRef) outputData);
CFMutableDataRef jpegData = CFDataCreateMutable(NULL, 0);
CGImageDestinationRef outputDestination = CGImageDestinationCreateWithData(jpegData, CGImageSourceGetType(outputImageSource), 1, NULL);

// add the image data to the destination
CGImageDestinationAddImageFromSource(jpegData, outputImageSource, 0, (__bridge CFDictionaryRef) metadata);

if (CGImageDestinationFinalize(outputDestination)) {
    NSLog(@"Successful image creation.");
    // process the image rendering, adjustment data creation and finalize the asset edit.
} else {
    NSLog(@"Image creation failed.");
}

メタデータを変更する必要がない場合は、CFDataRef を NSDictionary* にキャストする必要はありませんが、完全を期すためにここで行いました。

于 2014-09-22T01:14:58.230 に答える