Given CIImage, what's the fastest way to write data to disk?

I work with PhotoKit and implement filters that users can apply to photos in their Photo Library. I am currently getting an image by applying a filter, returning the edited version as CIImage

, and then converting CIImage

to NSData

with UIImageJPEGRepresentation

, so I can write this to disk. While this works great when users are trying to edit really large (e.g. 30MB) photos, it can take over 30 seconds, with 98% of the time being spent on UIImageJPEGRepresentation

(stat derived from tools).

I'm looking for a more efficient way to save my edited photo to disk without sacrificing quality if possible.

I understand that it UIImagePNGRepresentation

might result in better quality, but this is even slower than the JPEG rendering.

This is what I am doing now, on the default priority ( qos_class_utility

) thread :

func jpegRepresentationOfImage(image: CIImage) -> NSData {
    let eaglContext = EAGLContext(API: .OpenGLES2)
    let ciContext = CIContext(EAGLContext: eaglContext)

    let outputImageRef = ciContext.createCGImage(image, fromRect: image.extent())
    let uiImage = UIImage(CGImage: outputImageRef, scale: 1.0, orientation: UIImageOrientation.Up)

    return UIImageJPEGRepresentation(uiImage, 0.9) //this takes upwards of 20-30 seconds with large photos!
}

//writing out to disk:
var error: NSError?
let success = jpegData.writeToURL(contentEditingOutput.renderedContentURL, options: NSDataWritingOptions.AtomicWrite, error: &error)

      

+3


source to share


1 answer


I would suggest passing the CGImage directly to ImageIO using CGImageDestination. You can pass a dictionary to CGImageDestinationAddImage to specify 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
}

      

+5


source







All Articles