 <p>The way I've solved it was to render the context into a buffer and then write it to file as JPG. I'll have to further see how to optimise this flow on older gen iOS devices, but it seems to work well in comparison to createCGImage. This code is also useful for turning a CIImage into JPEG or bitmap NSData. Full sample code can be seen here: </p> <p><a href="https://github.com/mmackh/IPDFCameraViewController" rel="nofollow">https://github.com/mmackh/IPDFCameraViewController</a></p> <pre><code>static CIContext *ctx = nil; if (!ctx) { ctx = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace:[NSNull null]}]; } CGSize bounds = enhancedImage.extent.size; int bytesPerPixel = 8; uint rowBytes = bytesPerPixel * bounds.width; uint totalBytes = rowBytes * bounds.height; uint8_t *byteBuffer = malloc(totalBytes); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); [ctx render:enhancedImage toBitmap:byteBuffer rowBytes:rowBytes bounds:enhancedImage.extent format:kCIFormatRGBA8 colorSpace:colorSpace]; CGContextRef bitmapContext = CGBitmapContextCreate(byteBuffer,bounds.width,bounds.height,bytesPerPixel,rowBytes,colorSpace,kCGImageAlphaNoneSkipLast); CGImageRef imgRef = CGBitmapContextCreateImage(bitmapContext); CGColorSpaceRelease(colorSpace); CGContextRelease(bitmapContext); free(byteBuffer); if (imgRef == NULL) { goto release; } CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath]; CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypeJPEG, 1, NULL); CGImageDestinationAddImage(destination, imgRef, nil); CGImageDestinationFinalize(destination); CFRelease(destination); success = YES; goto release; release : { CFRelease(imgRef); if (success) { //completionHandler(filePath); } dispatch_resume(_captureQueue); } </code></pre>