2012-02-13 4 views
7

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

[[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 секунд на изображение. И это абсолютно долго.

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

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

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

ответ

2

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

+0

Я понимаю это. Но есть ли другой, более эффективный способ сделать это? Мне не нужен PNG. На самом деле любой формат в порядке. Мне просто нужно скопировать исходное изображение из ALAsset в мою собственную папку ...? Спасибо –

+0

Вы пробовали UIImageJPEGRepresentation? –

+0

Я просто попытался с представлением JPEG - это примерно на половину быстрее, чем представление PNG (еще около 1 секунды). Это намного лучше. Но я не ожидал этого. Есть ли еще что-нибудь? Как насчет разницы между обоими решениями, о которых я рассказывал. Имеет ли какие-либо преимущества перед другим? –

1

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

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

Это то, что я уже сделал ... –

9

Вместо этого вы можете скопировать исходные данные.
У этого есть преимущества, чтобы не перекодировать файл, не увеличивая размер файла, не теряя качества за счет дополнительного сжатия и сохраняя любые метаданные в файле. Должен быть также самым быстрым способом.
Предполагая, что у вас есть 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]; 
} 
+0

Проблема в том, что информация о ориентации изображения теряется – rydgaze

+0

Вы уверены, что не в метаданных exif? – GusOst

+0

Эта информация действительно находится в метаданных exif. – GusOst

Смежные вопросы