6

I create an image at url provided by PHContentEditingOutput. When I load data to UIImage and save it like this - it works.

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    NSData *data = [NSData dataWithContentsOfURL:contentEditingOutput.renderedContentURL]
    UIImage *image = [UIImage imageWithData:data];
    [PHAssetChangeRequest creationRequestForAssetFromImage:image];
} completionHandler:^(BOOL success, NSError *error) {
     ...
}];

But when I try approach with url it fails:

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:contentEditingOutput.renderedContentURL];
} completionHandler:^(BOOL success, NSError *error) {
     ...
}];

Error:

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

UPDATE:

The same error when I try to save a modification.

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    PHAssetChangeRequest *request = [PHAssetChangeRequest changeRequestForAsset:asset];
    request.contentEditingOutput = contentEditingOutput;
} completionHandler:^(BOOL success, NSError *error) {
     ...
}];

The method works for a video (creationRequestForAssetFromVideoAtFileURL:), but not for an image. What went wrong?

Tomasz Bąk
  • 6,124
  • 3
  • 34
  • 48
  • Wait - you've solved it already by using the first code, so what's the problem? – matt Feb 05 '15 at 16:50
  • You do know that `renderedContentURL` is something you are supposed to write to, not something you are supposed to read from - right? – matt Feb 05 '15 at 16:53
  • Yes, it solves the problem, but only partially. Please, look at the update. I am asking the question to get to the bottom of this. – Tomasz Bąk Feb 05 '15 at 20:52

2 Answers2

7

The problem is in the file format. I was trying to edit PNG screenshot, but renderingContentURL was always tmp/filename.JPG. At first I thought it was a bug, but according to the documentation this is correct behaviour.

renderedContentURL

Read this property to find a URL for writing edited asset content. Then, if editing a photo asset, write the altered photo image to a file in JPEG format at this URL. If editing a video asset, export the video to a QuickTime (.mov) file at this URL.

The solution is to convert the image with function

NSData *UIImageJPEGRepresentation(UIImage *image, CGFloat compressionQuality);
Tomasz Bąk
  • 6,124
  • 3
  • 34
  • 48
  • What's super annoying is PNG is a better image type AND internally they don't store the image in either JPEG or PNG. Apple has been pushing HEIC since 2017 all over the place and it seems sad that of all of the image formats, JPEG is the worst. – Waxhaw May 10 '20 at 19:48
2

When passing the metadata, I also had the issue consistently showing whenever the Orientation (inside the image metadata) was anything other than CGImagePropertyOrientationUp.

This is also stated inside the renderedContentURL documentation:

Edited asset content must incorporate (or “bake in”) the intended orientation of the asset. That is, the orientation metadata (if any) that you write in the output image or video file must declare the “up” orientation, and the image or video data must appear right-side up when presented without orientation metadata.

For images, the following metadata keys need to be updated (while the image data is also rotated):
kCGImagePropertyTIFFDictionary \ kCGImagePropertyTIFFOrientation
kCGImagePropertyOrientation
• possibly, kCGImagePropertyIPTCImageOrientation

alex-i
  • 5,406
  • 2
  • 36
  • 56