Огромные изображения в приложении для iOS без CATiledLayer?

У меня есть изображение размером около 7000x6000px. Мне нужно, чтобы это было в scrollview/imageView в моем приложении, однако это очень важно для отображения. Предполагается, что это своего рода карта. Я надеялся свести размер приложения к минимуму, а изображение в формате.jpg составляет всего около 13 МБ. В.png это более 100мб, что недопустимо. Многие предложили CATiledLayer как вариант, но я считаю, что это приведет к еще большим размерам файлов. Во всяком случае, я пытался сделать это с CATiledLayerи создать мои собственные плитки в TileCutter (плитки в.jpg), и размер не так уж плох. Но у меня повсюду ошибки. IOS версия CATiledLayer для меня загадка, и я не могу найти способ решить это. Я получаю сообщение об ошибке, сообщающее что-то о java-эквивалентном "индексе за пределами массива", даже если у массива есть содержимое по этому конкретному индексу. У него есть метод, который возвращает массив. Массив содержит данные.plist. Перед возвратом я выхожу из содержимого массива, давая мне хорошие данные. Звонок пытается получить доступ

[array objectAtIndex:0]

и положить его в словарь, но выбрасывает OutOfBounds. Когда вышел весь массив, я могу четко видеть содержимое, но когда вышел

NSLog("%@",[method objectAtIndex]); I get the same exception.

Тем не мение, CATiledLayer не дал мне ничего, кроме проблем. Я безуспешно занимался реинжинирингом проекта PhotoScroller. У кого-нибудь есть другие решения?

Благодарю.

2 ответа

Решение

У Apple есть этот действительно интересный проект PhotoScroller, который использует CATiledLayer и позволяет пролистывать несколько изображений и увеличивать их. Это казалось действительно опрятным, пока я не узнал, что Apple "обманула" и предварительно выложила изображения (около 800 плиток было сохранено в виде файла в комплекте!)

Мне нужна была аналогичная возможность, но мне нужно было загружать изображения из сети. Так возникла сеть PhotoScrollerNetwork. С TiledImageBuilder вы можете загружать (или читать с диска) массивные изображения - я даже протестировал изображение размером 18000x18000 - и оно работает.

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

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

У кого-то были проблемы с iPad 1 с его довольно ограниченной памятью, поэтому теперь класс ограничивает использование файловой системы при одновременной загрузке нескольких изображений. В этом году у меня была беседа с менеджером ядра iOS на WWDC, и после объяснения ему метода регулирования он сказал, что алгоритм (по управлению объемом использования дискового кэша), вероятно, является лучшим методом, который можно использовать.

Я думаю, что те, кто предложил CATiledLayer, правы. Вы должны действительно использовать это! Если вам нужен пример проекта, который отображает огромное растровое изображение с использованием этой технологии, посмотрите здесь: http://www.cimgf.com/2011/03/01/subduing-catiledlayer/

Многие технологии, которые мы используем в качестве разработчиков Cocoa/Cocoa Touch, не тронуты слабым сердцем, потому что часто мы просто не понимаем их, и их использование может показаться сложной задачей. Одна из этих технологий находится в Core Animation и называется CATiledLayer. Это похоже на магическую технологию, потому что большая часть ее реализации - это черный ящик, и этот факт способствует ее неправильному пониманию. CATiledLayer просто предоставляет способ рисовать очень большие изображения, не подвергаясь сильному удару памяти. Это важно независимо от того, где вы развертываете, но это особенно важно на устройствах iOS, так как память драгоценна, и когда ОС скажет вам освободить память, вы сможете это сделать, иначе ваше приложение будет закрыто. Этот пост предназначен для демонстрации того, что CATiledLayer работает так, как рекламируется, и реализовать его не так сложно, как могло бы показаться.

Другие вопросы по тегам