Как быстро сохранить образ ALAsset на диск на iOS? - PullRequest
7 голосов
/ 13 февраля 2012

Я использую ALAsset для получения таких изображений:

[[asset defaultRepresentation] fullResolutionImage]]

Это возвращает CGImageRef, который я хочу сохранить на диск как можно быстрее ...

Решение 1:

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

Решение 2:

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

Проблема в том, что оба метода очень медленно работают на устройстве.Мне требуется около 2 секунд на изображение, чтобы выполнить это.И это очень долго.

Вопрос: Как я могу ускорить процесс сохранения изображения?Или, может быть, есть лучшее решение для этого?

ОБНОВЛЕНИЕ: Наилучшим улучшением производительности в обоих решениях является сохранение изображений в формате JPEG вместо PNG.Таким образом, для решения 1 заменили UIImagePNGRepresentation на UIImageJPEGRepresentation.Для решения 2 заменили kUTTypePNG на kUTTypeJPEG.

Также стоит отметить, что второе решение более эффективно использует память, чем первое.

Ответы [ 3 ]

9 голосов
/ 23 ноября 2012

Вместо этого вы можете просто скопировать необработанные данные.
Преимущество этого заключается в том, что вы не перекодируете файл, не увеличите его размер, не потеряете качество из-за дополнительного сжатия и не сохраните метаданные в файле. Также должен быть самый быстрый способ.
Предполагая, что у вас есть theAsset и filepath для сохранения.
Также следует добавить обработку ошибок.

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];
}
2 голосов
/ 13 февраля 2012

Это из-за того, что сжатие PNG является медленным процессом и занимает много времени на процессоре iPhone, особенно для полноразмерной фотографии.

1 голос
/ 26 мая 2012

Нет такого способа ускорить процесс, но возможным решением было бы использование потоков, таким образом вы не заблокируете основную ветку и предложите пользователю лучший опыт:

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