PHAssetChangeRequest fails unless original image orientation is landscape left
Asked Answered
S

1

0

My PHAssetChangeRequest fails consistently even if I do not modify the NSData at all, and just try to reuse it when writing to PHContentEditingOutput's renderedContentURL when the image's orientation is anything other than landscape left (1).

I'll get the native pop-up asking for permission if it's landscape left. However if it's anything else, it fails silently (error code -1) and the only way I know it's an orientation issue is by viewing Device logs, where I see:

assetsd(Photos)[10493] <Notice>: Error: Invalid image orientation

Here's my code:

 [lastImageAsset
      requestContentEditingInputWithOptions:options
                          completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
       NSURL *imageURL = contentEditingInput.fullSizeImageURL;
       NSData *imageData = [NSData dataWithContentsOfURL:imageURL];

       PHContentEditingOutput *output = [[PHContentEditingOutput alloc]initWithContentEditingInput:contentEditingInput];
       PHAdjustmentData *adjustmentData = [[PHAdjustmentData alloc]initWithFormatIdentifier:@"Some Identifier" formatVersion:@"1.0" data:[@"Changed Something" dataUsingEncoding:NSUTF8StringEncoding]];
       [output setAdjustmentData:adjustmentData];
       [imageData writeToURL:output.renderedContentURL atomically:YES];

       [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
         PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest changeRequestForAsset:lastImageAsset];
         changeRequest.contentEditingOutput = output;
       } completionHandler:^(BOOL success, NSError * _Nullable error) {
         NSLog(@"%@, %i", error, success);
       }];
  }];

I've also tried

CIImage *inputImage = [CIImage imageWithContentsOfURL:imageURL];
inputImage = [inputImage imageByApplyingOrientation:contentEditingInput.fullSizeImageOrientation];

Thanks for your time.

UPDATE WITH SOLUTION

This works:

 [lastImageAsset
      requestContentEditingInputWithOptions:options
                          completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {

       NSURL *imageURL = contentEditingInput.fullSizeImageURL;

       CIImage *inputImage = [CIImage imageWithContentsOfURL:imageURL];
       inputImage = [inputImage imageByApplyingOrientation:contentEditingInput.fullSizeImageOrientation];

       EAGLContext *glContext = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
       CIContext *context = [CIContext contextWithEAGLContext:glContext];
       CGImageRef imageRef = [context createCGImage:inputImage fromRect:inputImage.extent];
       UIImage *image = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp];

       NSData *imageData = UIImageJPEGRepresentation(image, 1.0);


       PHContentEditingOutput *output = [[PHContentEditingOutput alloc]initWithContentEditingInput:contentEditingInput];
       PHAdjustmentData *adjustmentData = [[PHAdjustmentData alloc]initWithFormatIdentifier:@"Some Identifier" formatVersion:@"1.0" data:[@"Changed Something" dataUsingEncoding:NSUTF8StringEncoding]];
       [output setAdjustmentData:adjustmentData];
       [imageData writeToURL:output.renderedContentURL atomically:YES];

       [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
         PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest changeRequestForAsset:lastImageAsset];
         changeRequest.contentEditingOutput = output;
       } completionHandler:^(BOOL success, NSError * _Nullable error) {
         NSLog(@"%@, %i", error, success);
       }];
  }];
Semolina answered 3/8, 2017 at 16:56 Comment(0)
S
0

Okay finally found something that works:

CIImage *inputImage = [CIImage imageWithContentsOfURL:imageURL];
inputImage = [inputImage imageByApplyingOrientation:contentEditingInput.fullSizeImageOrientation];

EAGLContext *glContext = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
CIContext *context = [CIContext contextWithEAGLContext:glContext];
CGImageRef imageRef = [context createCGImage:inputImage fromRect:inputImage.extent];
UIImage *image = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationUp];

NSData *imageData = UIImageJPEGRepresentation(image, 1.0);

Now that imageData writes and maintains the orientation. Special thanks to https://github.com/vandadnp/iOS-8-Swift-Programming-Cookbook/blob/master/chapter-camera/Editing%20Images%20and%20Videos%20Right%20on%20the%20Device/Editing%20Images%20and%20Videos%20Right%20on%20the%20Device/ViewController.swift

Semolina answered 3/8, 2017 at 19:27 Comment(2)
congrats! :D .. please update your question with the complete solution for other people who may have the same issue in the future :)Verruca
Sure thing Marcio! And thanks for taking my message :)Semolina

© 2022 - 2025 — McMap. All rights reserved.