У меня есть собственный класс загрузчика изображений, он содержит очередь и загружает изображения один (или определенное количество) за раз, записывает их в папку кэша и извлекает их из папки кеша, когда необходимо. У меня также есть подкласс UIImageView, к которому я могу передать URL-адрес, через класс загрузчика изображений он будет выглядеть, если изображение уже существует на устройстве и покажет его, если оно есть, или загрузите и покажите его после его завершения.UIImage to raw NSData/избежать сжатия
После завершения загрузки изображения я делаю следующее. Я создаю UIImage из загруженных NSData, сохраняю загруженные NSData на диск и возвращаю UIImage.
// This is executed in a background thread
downloadedImage = [UIImage imageWithData:downloadedData];
BOOL saved = [fileManager createFileAtPath:filePath contents:downloadedData attributes:attributes];
// Send downloadedImage to the main thread and do something with it
Чтобы получить существующее изображение, я делаю это.
// This is executed in a background thread
if ([fileManager fileExistsAtPath:filePath])
{
NSData* imageData = [fileManager contentsAtPath:filePath];
retrievedImage = [UIImage imageWithData:imageData];
// Send retrievedImage to the main thread and do something with it
}
Как вы можете видеть, я всегда создавать UIImage непосредственно из загруженного NSData, я никогда не создавать NSData с помощью UIImagePNGRepresentation так что изображение никогда не будет сжиматься. Когда вы создаете UIImage из сжатых NSData, UIImage распаковывает его прямо перед рендерингом в основном потоке и тем самым блокирует пользовательский интерфейс. Поскольку у меня теперь есть UITableView с тонны маленьких изображений, которые нужно загрузить или извлечь с диска, это было бы неприемлемо, так как это сильно замедляло бы мою прокрутку.
Теперь моя проблема. Пользователь также может выбрать фотографию из рулона камеры, сохранить ее, и она также должна появиться в моем UITableView. Но я не могу найти способ превратить UIImage из рулона камеры в NSData, не используя UIImagePNGRпредставление. Итак, вот мой вопрос.
Как я могу конвертировать UIImage в несжатые NSData, чтобы впоследствии преобразовать его обратно в UIImage с помощью imageWithData, чтобы его не нужно было распаковать перед рендерингом?
или
Есть ли способ, что я могу сделать декомпрессию перед отправкой UIImage в основной поток и кэшировать поэтому он имеет только распаковывать один раз?
Заранее спасибо.
Привет, спасибо за Ваш ответ. Я уже использую фоновый поток для загрузки изображений. Изображения представляют собой размер, который они отображаются в таблицеView, поэтому они могут быть как можно меньше. И когда они загружаются с диска, я сохраняю их в памяти столько, сколько могу. Но этого все еще не хватало, когда прокручивалось через мой стол. Декомпрессия занимала около 1/3 времени. Я использовал ваше предложение для использования ImageIO, в CGImageSourceCreateImageAtIndex я установил kCGImageSourceShouldCache в YES. Теперь он сохраняет несжатую версию в памяти, и она работает быстрее. Благодарю. – David
Очень приятно! Я все еще немного обеспокоен; Я надеюсь, что вы проверите с помощью инструментов и убедитесь, что все хорошо, когда пользователь прокручивает представление таблицы на самом устройстве. – matt
Я использовал профилировщик времени, на самом деле, как я узнал, что именно распаковка вызвала такие огромные задержки. copyImageBlockSetPNG и png_read_now были функциями, занимающими 1/3 времени. Я тестирую iPhone 3GS и iPod Touch 4G, два самых медленных устройства, поддерживаемых нашим приложением. Даже если я отключу кэширование и загружаю изображения с диска каждый раз, когда они становятся видимыми, я могу лишь немного увидеть пустой образ перед тем, как будет отображаться изображение, но пользовательский интерфейс вообще не висит. И при включенном кешировании это совершенно незаметно. Это получилось великолепно, поэтому еще раз спасибо. – David