3

I'm trying to save an image that is currently in my image view to the Camera Roll. The image I'm trying to save shows up perfectly in the image view, via [mainImage setImage:outputImage]; However, when I try to press the button that saves the image:

- (IBAction)saveImage:(id)sender {

    UIImageWriteToSavedPhotosAlbum([mainImage image], self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

}

-(void)image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(void*)contextInfo{
    NSLog(@"%@", [error localizedDescription]);
}

The camera roll is empty. I'm using iOS7 simulator. Any help would be appreciated!

EDIT: The Assertion doesn't say anything either.

~Carpetfizz

Carpetfizz
  • 8,707
  • 22
  • 85
  • 146
  • 2
    Take advantage of the rest of the parameters to `UIImageWriteToSavedPhotosAlbum`. The selector that is called has an error parameter you can look at to see why it is failing. – rmaddy Nov 11 '13 at 20:06
  • 1
    Thanks for the suggestion, but I get `(null)` as the error. – Carpetfizz Nov 11 '13 at 20:18
  • Is `image` nil or not in the callback method? – rmaddy Nov 11 '13 at 20:19
  • Has the app ever prompted you for permission to access your photos? You can check using [ALAssetsLibrary authorizationStatus] to see if the app has permission. – ryan cumley Nov 11 '13 at 20:29
  • Yes, it asked for my permission, and it's enabled in the Privacy tab. – Carpetfizz Nov 11 '13 at 23:52
  • It's absolutely late, but for anyone having the same issue, refer to https://stackoverflow.com/a/46396718/7113238 – Lawliet Sep 25 '17 at 02:18

2 Answers2

14

This took me a while to figure out...

I am not exactly sure why, but if the UIImage you are trying to save is backed by a CIImage (i.e. image.cgImage == nil), UIImageWriteToSavedPhotosAlbum will oddly successfully complete with a nil error object in the completion handler, but nothing will show up in photos.

If this is the case, you can convert the UIImage's CIImage to a CGImage (Swift 4.1):

// this could also be made into an extension
func cgImage(from ciImage: CIImage) -> CGImage? {
    let context = CIContext(options: nil)
    return context.createCGImage(ciImage, from: ciImage.extent)
}

Then convert back to a UIImage (these two steps can be combined):

guard let ciImage = image.ciImage else { return }
guard let cgImage = cgImage(from: ciImage) else { return } // the above function

let newImage = UIImage(cgImage: cgImage) // ready to be saved!

I hope this solution can save someone the aggravation that this problem caused me .

jason z
  • 1,377
  • 13
  • 19
1

I had a similar problem and searched for the answer. Though I am not sure it's exact the same cause, I hope this can give you a little insight.

My suggestion is to check [mainImage image]. It might return nil even it shows up perfectly in image view.

In my case, I should use info[UIImagePickerControllerOriginalImage] instead of info[UIImagePickerControllerEditedImage], which returns nil and that's why it was never saved.

Weishi Z
  • 1,629
  • 5
  • 18
  • 38