Как ускорить сохранение изображения UIImagePickerController с камеры в файловую систему через UIImagePNGRepresentation ()? - PullRequest
4 голосов
/ 04 октября 2011

Я создаю приложения, которые позволяют пользователям делать фотографии и показывать их в виде эскизов и просмотра фотографий. У меня есть класс NSManagedObject с именем photo, а photo имеет метод, который принимает UIImage и преобразует его в PNG с помощью UIImagePNGRepresentation () и сохраняет его в файловой системе. После этой операции измените размер изображения до размера миниатюры и сохраните его.

Проблема здесь в UIImagePNGRepresentation (), и преобразование размера изображения кажется очень медленным, и я не знаю, является ли это правильным способом сделать это.

Скажи мне, если кто-нибудь знает лучший способ выполнить то, что я хочу сделать.

Заранее спасибо.

Ответы [ 4 ]

2 голосов
/ 08 ноября 2012

В зависимости от разрешения изображения, UIImagePNGRepresentation действительно может быть довольно медленным, как и любая запись в файловую систему.

Вы должны всегда выполнять эти типы операций в асинхронной очереди. Даже если производительность при тестировании кажется достаточно хорошей для вашего приложения, вы все равно должны делать это в асинхронной очереди - вы никогда не знаете, какие другие процессы могут выполняться на устройстве, что может замедлить сохранение, как только ваше приложение в руках пользователей.

Более новые версии iOS делают асинхронное и очень простое сохранение с помощью Grand Central Dispatch (GCD). Шаги:

  1. Создайте NSBlockOperation, который сохраняет изображение
  2. В блоке завершения операции блока прочитайте изображение с диска и отобразите его. Единственное предостережение: вы должны использовать основную очередь для отображения изображения: все операции пользовательского интерфейса должны выполняться в главном потоке .
  3. Добавьте операцию блокировки в очередь операций и посмотрите, как она работает!

Вот и все. И вот код:

// Create a block operation with our saves
NSBlockOperation* saveOp = [NSBlockOperation blockOperationWithBlock: ^{

   [UIImagePNGRepresentation(image) writeToFile:file atomically:YES];
   [UIImagePNGRepresentation(thumbImage) writeToFile:thumbfile atomically:YES];

}];

// Use the completion block to update our UI from the main queue
[saveOp setCompletionBlock:^{

   [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 

      UIImage *image = [UIImage imageWithContentsOfFile:thumbfile];
      // TODO: Assign image to imageview

   }];
}];

// Kick off the operation, sit back, and relax. Go answer some stackoverflow
// questions or something.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:saveOp];

Как только вы освоитесь с этим шаблоном кода, вы обнаружите, что часто его используете. Это невероятно полезно при генерации больших наборов данных, длительных операций при нагрузке и т. Д. По сути, любая операция, которая делает ваш пользовательский интерфейс в меньшей степени медленным, является хорошим кандидатом для этого кода. Просто помните, что вы ничего не можете сделать с пользовательским интерфейсом, пока не находитесь в основной очереди, а все остальное - торт.

0 голосов
/ 04 октября 2011

Да, на iPhone 4 требуется время, когда размер изображения составляет около 6 МБ. Решение состоит в том, чтобы выполнить UIImagePNGRepresentation() в фоновом потоке, используя performSelectorInBackground:withObject:, чтобы ваш поток пользовательского интерфейса не зависал.

0 голосов
/ 04 октября 2011

Вероятно, будет гораздо быстрее выполнить изменение размера перед преобразованием в PNG.

0 голосов
/ 04 октября 2011

Попробуйте UIImageJPEGRepresentation со средним качеством сжатия.Если узким местом является IO, это может оказаться быстрее, так как размер файла обычно будет меньше png.

Используйте инструменты, чтобы проверить, является ли UIImagePNGRepresentation медленной частью или записывает ли данные в файловую систему, которая являетсямедленно.

...