How to quickly save an ALAsset image to disk on iOS?

I use ALAsset to get these images:

[[asset defaultRepresentation] fullResolutionImage]] 

This returns the CGImageRef, which I want to save to disk as quickly as possible ...

Solution 1:

 UIImage *currentImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]]; NSData *currentImageData = UIImagePNGRepresentation(currentImage); [currentImageData writeToFile:filePath atomically:YES]; 

Solution 2:

 CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath]; CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL); CGImageDestinationAddImage(destination, [[asset defaultRepresentation] fullResolutionImage], nil); CGImageDestinationFinalize(destination); 

The problem is that both methods are very slow on the device. For this, I take about 2 seconds per image. And it is absolutely long.

Question: How can I speed up this process of saving images? Or maybe there is a better solution for this?

UPDATE: The best performance improvements in both solutions are saving JPEG images instead of PNG. Therefore, for solution 1, the UIImagePNGRepresentation replaced by the UIImageJPEGRepresentation . For solution 2, replace kUTTypePNG with kUTTypeJPEG .

It is also worth noting that the second solution is a more efficient memory than the first.

+7
source share
3 answers

This is because PNG compression is a slow process and takes some time on the iPhone processor, especially for full-size photography.

+2
source

Instead, you can copy the original data.
This has the advantage of not re-encoding the file, rather than increasing the file size, rather than losing quality by additional compression and saving any metadata in the file. There should also be the fastest way.
Assuming you have theAsset and filepath to save it.
You should also add error handling.

 long long sizeOfRawDataInBytes = [[theAsset defaultRepresentation] size]; NSMutableData* rawData = [NSMutableData dataWithLength:(NSUInteger) sizeOfRawDataInBytes]; void* bufferPointer = [rawData mutableBytes]; NSError* error=nil; [[theAsset defaultRepresentation] getBytes:bufferPointer fromOffset:0 length:sizeOfRawDataInBytes error:&error]; if (error) { NSLog(@"Getting bytes failed with error: %@",error); } else { [rawData writeToFile:filepath atomically:YES]; } 
+9
source

There is such a way to speed up the process, but a possible solution would be to use threads, so you will not block mainthread, and you will offer the user the best experience:

 dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(dispatchQueue, ^(void) { // Your code here }); 
+1
source

All Articles