Search code examples
iosuiimagecgimage

Save CIImage, by converting to CGImage, throws an error


I have an image I'm grabbing from AVFoundation:

[stillImage captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
    NSLog(@"image capture");

    NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
    UIImage *image = [[UIImage alloc] initWithData:imageData];

I'm then cropping this image by first converting to a CIImage:

beginImage = [CIImage imageWithCVPixelBuffer:CMSampleBufferGetImageBuffer(imageSampleBuffer) options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNull null], kCIImageColorSpace, nil]];

    //first we crop to a square
    crop = [CIFilter filterWithName:@"CICrop"];
    [crop setValue:[CIVector vectorWithX:0 Y:0 Z:70 W:70] forKey:@"inputRectangle"];
    [crop setValue:beginImage forKey:@"inputImage"];
    croppedColourImage = [crop valueForKey:@"outputImage"];

I'm then trying to convert this back to a CGImage so that I can save it out:

CGImageRef cropColourImage = [context createCGImage:croppedColourImage fromRect:[croppedColourImage extent]];
    UIImage *cropSaveImage = [UIImage imageWithCGImage:cropColourImage];


    //saving of the images
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

     [library writeImageToSavedPhotosAlbum:[cropSaveImage CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
     if (error) {
         NSLog(@"ERROR in image save :%@", error);
     } else
     {
         NSLog(@"SUCCESS in image save");
     }

     }];

However, this throws the error:

ERROR in image save :Error Domain=ALAssetsLibraryErrorDomain Code=-3304 "Failed to encode image for saved photos." UserInfo=0x19fbd0 {NSUnderlyingError=0x18efa0 "Failed to encode image for saved photos.", NSLocalizedDescription=Failed to encode image for saved photos.}

I've read elsewhere that this can happen if the image was 0x0 pixels, and that the conversion from CIImage to CGImage can cause the problem. Any ideas?

Thank you.


Solution

  • I got it working!

    What I did is replace all my code with:

    NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
    UIImage *image = [[UIImage alloc] initWithData:imageData];
    NSLog(@"*image size is: %@", NSStringFromCGSize(image.size));
    
    //test creating a new ciimage
    CIImage *ciImage = [[CIImage alloc] initWithCGImage:[image CGImage]];
    NSLog(@"ciImage extent: %@", NSStringFromCGRect([ciImage extent]));
    

    This gives me a usable CIImage. I can then have filter fun with it, before saving it with:

    CIImage *croppedColourImage = [crop outputImage];
    
    //convert it to a cgimage for saving
    CGImageRef cropColourImage = [context createCGImage:croppedColourImage fromRect:[croppedColourImage extent]];
    
    //saving of the images
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    
    [library writeImageToSavedPhotosAlbum:cropColourImage metadata:[croppedColourImage properties] completionBlock:^(NSURL *assetURL, NSError *error){
        if (error) {
            NSLog(@"ERROR in image save: %@", error);
        } else
        {
            NSLog(@"SUCCESS in image save");
            CGImageRelease(cropColourImage);
        }
    }];