Given a CIImage, what is the fastest way to write image data to disk?
I would suggest passing the CGImage directly to ImageIO using CGImageDestination. You can pass a dictionary to CGImageDestinationAddImage to indicate the compression quality, image orientation, etc.
CFDataRef save_cgimage_to_jpeg (CGImageRef image)
{
CFMutableDataRef cfdata = CFDataCreateMutable(nil,0);
CGImageDestinationRef dest = CGImageDestinationCreateWithData(data, CFSTR("public.jpeg"), 1, NULL);
CGImageDestinationAddImage(dest, image, NULL);
if(!CGImageDestinationFinalize(dest))
; // error
CFRelease(dest);
return cfdata
}
Try using the CIContext method writeJPEGRepresentation (available iOS 10) as follows to eschew UIImage and make the writing faster.
extension CIImage {
@objc func saveJPEG(_ name:String, inDirectoryURL:URL? = nil, quality:CGFloat = 1.0) -> String? {
var destinationURL = inDirectoryURL
if destinationURL == nil {
destinationURL = try? FileManager.default.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
}
if var destinationURL = destinationURL {
destinationURL = destinationURL.appendingPathComponent(name)
if let colorSpace = CGColorSpace(name: CGColorSpace.sRGB) {
do {
let context = CIContext()
try context.writeJPEGRepresentation(of: self, to: destinationURL, colorSpace: colorSpace, options: [kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption : quality])
return destinationURL.path
} catch {
return nil
}
}
}
return nil
}
}
The @objc keyword enables you to call the method in Objective-C as:
NSString* path = [image saveJPEG:@"image.jpg" inDirectoryURL:url quality:1.0];
For PNG there is a similar method writePNGRepresentation for iOS 11:
if #available(iOS 11.0, *) {
if let colorSpace = CGColorSpace(name: CGColorSpace.sRGB) {
do {
let format = CIFormat.RGBA8
try context.writePNGRepresentation(of: self, to: destinationURL, format: format, colorSpace: colorSpace)
return destinationURL.path
} catch {
return nil
}
}
}